home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 2 / Gekikoh Dennoh Club Vol. 2 (Japan).7z / Gekikoh Dennoh Club Vol. 2 (Japan) (Track 01).bin / fsw / zm302 / zm302_s.lzh / MPSRC045.LZH / MPCM.HAS < prev    next >
Text File  |  1996-11-22  |  111KB  |  3,810 lines

  1. *///////////////////////////////////////////////////////////////
  2. *
  3. *    Modulatable (ad)PCM driver MPCM.x version 0.45
  4. *
  5. *        重い、重いぜー
  6. *
  7. *///////////////////////////////////////////////////////////////
  8.  
  9.  
  10.         .include    doscall.mac
  11.         .include    iocscall.mac
  12.  
  13.         .include    mpcmcall.mac
  14.         .include    mpcm_prg.mac
  15.  
  16. *---------------------------------------------------------------
  17. *          定数定義
  18. *---------------------------------------------------------------
  19.  
  20. TAB        equ        $09
  21. CR        equ        $0d
  22. LF        equ        $0a
  23. EOF        equ        $1a
  24.  
  25. DMA0        equ        $00e84000    * DMAチャンネル#0
  26. DMA1        equ        $00e84040    * DMAチャンネル#1
  27. DMA2        equ        $00e84080    * DMAチャンネル#2
  28. DMA3        equ        $00e840c0    * DMAチャンネル#3
  29. CSR        equ        $00
  30. CER        equ        $01
  31. DCR        equ        $04
  32. OCR        equ        $05
  33. SCR        equ        $06
  34. DCCR        equ        $07
  35. MTC        equ        $0a
  36. MAR        equ        $0c
  37. DAR        equ        $14
  38. BTC        equ        $1a
  39. BAR        equ        $1c
  40. NIV        equ        $25
  41. EIV        equ        $27
  42. MFC        equ        $29
  43. CPR        equ        $2d
  44. DFC        equ        $31
  45. BFC        equ        $39
  46. GCR        equ        $3f
  47.  
  48. MFP        equ        $00e88000    * MFPアドレス
  49. SYSTEMP        equ        $00e8e000    * システムポートアドレス
  50. OPM        equ        $00e90000    * OPMアドレス
  51. ADPCM        equ        $00e92000    * ADPCMアドレス
  52. PPI        equ        $00e9a004    * PPI(i8255)ポートC
  53. SPRITEC        equ        $00eb0000    * スプライトコントローラアドレス
  54.  
  55. TEXT_RAM    equ        $00e00000    * テキストRAM
  56. G_RAM        equ        $00c00000    * グラフィックRAM
  57. TEXT_PALET    equ        $00e82200    * テキストパレット
  58. G_PALET        equ        $00e82000    * グラフィックパレット
  59. SP_PALET    equ        $00e82200    * スプライトパレット(=TEXT_PALET)
  60.  
  61. ADPCM_SYSWORK    equ        $0c32        * IOCS用の動作状態ワーク(_ADPCMSNSで参照)
  62.  
  63. MIX_SIZE    equ        48        * 1回の割り込みで処理するADPCMのバイト数
  64. CH_MAX        equ        16        * 演奏用最大発音数
  65. CH_WORK_SIZE    equ        128        * 各PCMチャンネルのワークサイズ
  66. EFCT_MAX    equ        8        * 効果音最大発音数
  67. EFCT_WORK_SIZE    equ        64        * 各PCMチャンネルのワークサイズ
  68.  
  69.         .offset        0        * 音楽専用チャンネルのワーク
  70.  
  71. CH_JMP_ADR:    .ds.l        1        * (.l) PCMの種類による処理先アドレス
  72. CH_JMP_ADR2:    .ds.l        1        * (.l) 音量による処理先アドレス
  73. CH_TOP_ADR:    .ds.l        1        * (.l) PCMの先頭アドレス
  74. CH_END_ADR:    .ds.l        1        * (.l) PCMの最終アドレス
  75. CH_LPSTART_ADR:    .ds.l        1        * (.l) ループの先頭PCMアドレス
  76. CH_LPEND_ADR:    .ds.l        1        * (.l) ループの終端PCMアドレス
  77. CH_LPTIME:    .ds.l        1        * (.l) ループの回数
  78. CH_LPTIME_CTR:    .ds.l        1        * (.l) ループの回数ワーク
  79. CH_PCM_ADR:    .ds.l        1        * (.l) 現在処理中のPCMアドレス
  80. CH_LOOP_X:    .ds.l        1        * (.l) ループ時のADPCM->PCM変換テーブルアドレス
  81. CH_LOOP_Y:    .ds.w        1        * (.w) ループ時点ADPCM->PCM変換の基本PCMデータ
  82. CH_LAST_PCM:    .ds.w        1        * (.w) 前回処理終了時のPCM値
  83. CH_PITCH_CADR:    .ds.l        1        * (.l) 周波数に応じた音程変換ルーチンアドレス
  84. CH_ORG_PITCH:    .ds.l        1        * (.l) CH_USER_NOTE/CH_ORG_NOTEから算出した音程
  85. CH_PITCH:    .ds.l        1        * (.l) 周波数に応じて変換された音程
  86. CH_PITCH_CTR:    .ds.w        1        * (.w) 前回割り込み終了時の音程カウンタ下位
  87. CH_PAN:        .ds.w        1        * (.w) PCMのPAN(0-127)
  88. CH_TRAP_ADR:    .ds.l        1        * (.l) 変換がこのアドレスに及ぶとジャンプする
  89. CH_TRAP_ROUTINE:.ds.l        1        * (.l) そのジャンプ先の処理アドレス
  90. CH_CHANNEL_MASK:.ds.l        1        * (.l) 各チャンネルに対応したビットマスク
  91. CH_TPCNST_CADR:    .ds.l        1        * (.l) PCMアドレス増分計算ルーチンアドレス
  92. CH_TPCNST:    .ds.l        1        * (.l) 1回の割り込みでのPCMアドレス増分
  93. CH_AtoP_X:    .ds.l        1        * (.l) 処理中のADPCM->PCM変換テーブルアドレス
  94. CH_AtoP_Y:    .ds.w        1        * (.w) 処理中のADPCM->PCM変換基本PCMデータ
  95. CH_ORG_NOTE:    .ds.w        1        * (.w) PCMデータの原音程
  96. CH_USER_NOTE:    .ds.w        1        * (.w) ユーザ指定の音階(発音する音階)
  97. CH_USER_VOL:    .ds.w        1        * (.w) ユーザ指定の音量($0000~$0040~$007f)
  98. CH_VOL:        .ds.w        1        * (.w) 音量($0000~$0040~$007f)
  99. CH_VOL_OFFS:    .ds.w        1        * (.w) 変換ルーチンアドレステーブルのオフセット
  100. CH_CNVADR_BASE:    .ds.l        1        * (.w) 変換ルーチンアドレステーブルのベースアドレス
  101. CH_LAST_VPCM:    .ds.w        1        * (.w) 音量変換後の最後の16bitPCM
  102. CH_ODDEVEN:    .ds.b        1        * (.b) CH_LAST_PCMが偶数番目か奇数番目か
  103. CH_KEY_STAT:    .ds.b        1        * (.b) KEY 状態 $01=keyon $80=keyoff $00=non
  104. CH_PLAY_FLAG:    .ds.b        1        * (.b) 演奏フラグ(演奏中=$ff/演奏終了=$00)
  105. CH_USER_FRQ:    .ds.b        1        * (.b) ユーザが指定した周波数
  106. CH_PCM_KIND:    .ds.b        1        * (.b) 登録されているPCMの種類
  107.                         *    $ff=ADPCM / $00=none / $01=16bit / $02=8bit
  108.         .even
  109. CH_DEBUG_PCM_HEADER_ADR:.ds.l    1        * (.l) デバッグ用 PCM登録ヘッダアドレス
  110.  
  111.  
  112.         .offset        0        * 効果音専用チャンネルのワーク
  113.  
  114. EFCT_JMP_ADR:    .ds.l        1        * (.l) 処理ルーチンアドレス(周波数による)
  115. EFCT_PCM_ADR:    .ds.l        1        * (.l) 現在再生中のPCMアドレス
  116. EFCT_PCM_LEN:    .ds.l        1        * (.l) 残りPCMの長さ
  117. EFCT_CTBL_ADR:    .ds.l        1        * (.l) チェーンテーブルアドレス
  118. EFCT_CH_MASK:    .ds.l        1        * (.l) チャンネルマスク
  119. EFCT_AtoP_X:    .ds.l        1        * (.l) ADPCM -> PCM 変換テーブルアドレス
  120. EFCT_AtoP_Y:    .ds.w        1        * (.w) ADPCM -> PCM 変換 Y
  121. EFCT_CTBL_N:    .ds.w        1        * (.w) チェーンテーブル処理数
  122. EFCT_PAN:    .ds.w        1        * (.w) PCMのPAN(0-127)
  123. EFCT_FRQ:    .ds.w        1        * (.w) PCMのFRQ
  124. EFCT_PLAY_FLAG:    .ds.b        1        * (.b) 演奏状態フラグ
  125. EFCT_PLAY_MODE:    .ds.b        1        * (.b) 再生モード(00:通常 01:アレイ 02:リンクアレイ)
  126. EFCT_PCM_KIND:    .ds.b        1        * (.b) 登録されているPCMの種類
  127.         .text
  128.  
  129. *▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
  130. *
  131. *        常駐部分データ
  132. *
  133. *△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△
  134.  
  135. *        初期化関係
  136.  
  137.         .align        4
  138.  
  139. header:        .dc.b        'mPCm/WAC'    * 常駐判定用ヘッダ
  140. trap1_vec_buff:    .ds.l        1        * trap #1 ベクタ保存
  141. DMA_vec_buff:    .ds.l        1        * DMA転送終了割り込みベクタ保存
  142. DMAERR_vec_buff:.ds.l        1        * DMA転送エラー割り込みベクタ保存
  143. iocs_vecs:    .ds.l        8        * 元のIOCSベクタ保存
  144. mpcm_locked:    .dc.b        0        * 占有カウント(0:unlocked / 1-$ff:locked)
  145. mpcm_debug:    .dc.b        0        * デバッグフラグ
  146.  
  147. *        TRAP #1 関係
  148. trap1_sr_mask:    .dc.w        $0200        * trap #1 実行中の sr のmask
  149. trap1_nest:    .dc.w        -1        * trap #1 呼出ネスト回数
  150.  
  151. *        DMA 割り込み関係
  152.  
  153.         .align        4
  154. ch0_work:    .ds.b        CH_WORK_SIZE*CH_MAX    * 各PCMチャンネルのワーク
  155.  
  156. efct0_work:    .ds.b        EFCT_WORK_SIZE*EFCT_MAX    * 効果音チャンネル
  157.  
  158. IOCS_work:    .ds.b        EFCT_WORK_SIZE        * IOCS用の1チャンネル
  159.  
  160.         .align        4
  161. IOCS_REC_LEN:    .ds.l        1        * ADPCM録音時の残り長さ
  162. IOCS_REC_CTBL_ADR:.ds.l        1        * (.l) チェーンテーブルアドレス
  163. IOCS_REC_CTBL_N:.ds.w        1        * (.l) チェーンテーブル処理数
  164.  
  165.  
  166.         .align        4
  167. PtoA_X:        .dc.l        PtoA_tbl    * PCM -> ADPCM 変換テーブルアドレス
  168. PtoA_Y:        .dc.w        0        * PCM -> ADPCM 予測値
  169. ADPCM_pan:    .dc.b        0        * ADPCM の PAN
  170. pan_set_flag:    .dc.b        0        * pan設定フラグ
  171. play_flag:    .dc.l        0        * チャンネル演奏状態(bit 1=play/0=off)
  172. mpcm_nest:    .dc.w        -1        * mpcm多重割り込みの回数
  173. overload_ctr:    .dc.w        -100        * 過負荷時のカウンタ
  174. IMR_mask:    .dc.l        $00df0000    * 割り込み中の MFP mask(MFP+$12から)
  175. MPU_mask:    .dc.w        $0300        * 割り込み中の mpu mask
  176. ADPCM_out_flag:    .dc.b        -1        * ADPCM 出力バッファセレクタ
  177. DMA_err_stat:    .dc.b        0        * DMAエラーコード(CERレジスタの内容)
  178. mpcm_mode:    .dc.l        $00000000    * MPCM 動作モードの状態
  179. efct_poly:    .dc.w        $0000        * 効果音発声数
  180. frq_offset:    .dc.w        $0000        * 内臓ADPCM高音質化対応JMPテーブルオフセット
  181. pitch_mode:    .dc.b        $00        * 音程固定フラグ
  182. volume_mode:    .dc.b        $00        * 音量固定フラグ
  183.  
  184.     .ifdef    DEBUG
  185. ofwrite:        .dc.l        TEXT_RAM    * オーバーフロー検出書き込みアドレス
  186.     .endif
  187.     .ifdef    FCTRACE
  188. fc_logadr:        .dc.l        TEXT_RAM+$40000    * 関数呼びだしログバッファ
  189.     .endif
  190.  
  191. mplock_app_name:.ds.b        32*32        * mpcmをロックしているアプリ名称バッファ
  192.  
  193.         .even
  194.  
  195. PCM_out:    .ds.b        MIX_SIZE*4    * PCM 合成用バッファ
  196. ADPCM_out0:    .ds.b        MIX_SIZE    * ADPCM 作成/出力用バッファ0
  197. ADPCM_out1:    .ds.b        MIX_SIZE    * ADPCM 作成/出力用バッファ1
  198.  
  199. dummy_ADPCM:    .dc.b        $88,$88,$88,$88,$88,$88,$88,$88    * ダミー再生ADPCM
  200.         .dc.b        $80,$80,$80,$80,$80,$80,$80,$80
  201.         .dc.b        $80,$80,$80,$80,$80,$80,$80,$80
  202.         .dc.b        $80,$80,$80,$80,$80,$80,$80,$80
  203.         .dc.b        $80,$80,$80,$80,$80,$80,$80,$80
  204.         .dc.b        $80,$80,$80,$80,$80,$80,$80,$80
  205.  
  206.         .align        4
  207. mpw:                            * システムワークポインタアドレス
  208.  
  209. pan_tbl3:    .dc.b        $03,$01,$02,$00        *   3段階指定
  210. pan_tbl128:    .dc.b        $01,$00,$00,$02        * 128段階指定
  211.  
  212.         .align        4
  213.  
  214. *        効果音用再生ルーチンのジャンプテーブル
  215.                             * ADPCM動作周波数
  216.                             * 7kHz        15kHz        31kHz
  217. AtoP_EFCT_tbl:    .dc.l        AtoP_EFCT01_08        * (none)    (none)        3.9kHz    
  218.         .dc.l        AtoP_EFCT01_06        * (none)    (none)        5.2kHz
  219.         .dc.l        AtoP_EFCT01_04        * (none)    3.9kHz        7.8kHz
  220.         .dc.l        AtoP_EFCT01_03        * (none)    5.2kHz        10.4kHz
  221.         .dc.l        AtoP_EFCT01_02        * 3.9kHz    7.8kHz        15.6kHz
  222.         .dc.l        AtoP_EFCT02_03        * 5.2kHz    10.4kHz        20.8kHz
  223.         .dc.l        AtoP_EFCT01_01        * 7.8kHz    15.6kHz        31.2kHz
  224.         .dc.l        AtoP_EFCT04_03        * 10.4kHz    20.8kHz        (none)
  225.         .dc.l        AtoP_EFCT02_01        * 15.6kHz    31.2kHz        (none)
  226.         .dc.l        AtoP_EFCT08_03        * 20.8kHz    (none)        (none)
  227.         .dc.l        AtoP_EFCT04_01        * 31.2kHz    (none)        (none)
  228.  
  229. PCM16_EFCT_tbl:    .dc.l        PCM16_EFCT01_08
  230.         .dc.l        PCM16_EFCT01_06
  231.         .dc.l        PCM16_EFCT01_04
  232.         .dc.l        PCM16_EFCT01_03
  233.         .dc.l        PCM16_EFCT01_02
  234.         .dc.l        PCM16_EFCT02_03
  235.         .dc.l        PCM16_EFCT01_01
  236.         .dc.l        PCM16_EFCT04_03
  237.         .dc.l        PCM16_EFCT02_01
  238.         .dc.l        PCM16_EFCT08_03
  239.         .dc.l        PCM16_EFCT04_01
  240.  
  241. PCM8_EFCT_tbl:    .dc.l        PCM8_EFCT01_08
  242.         .dc.l        PCM8_EFCT01_06
  243.         .dc.l        PCM8_EFCT01_04
  244.         .dc.l        PCM8_EFCT01_03
  245.         .dc.l        PCM8_EFCT01_02
  246.         .dc.l        PCM8_EFCT02_03
  247.         .dc.l        PCM8_EFCT01_01
  248.         .dc.l        PCM8_EFCT04_03
  249.         .dc.l        PCM8_EFCT02_01
  250.         .dc.l        PCM8_EFCT08_03
  251.         .dc.l        PCM8_EFCT04_01
  252.  
  253. *        演奏用再生ルーチンのジャンプテーブル
  254.  
  255. AtoP_high_tbl:    .dc.l        AtoP_high_v00,AtoP_high_v01,AtoP_high_v02,AtoP_high_v03
  256.         .dc.l        AtoP_high_v04,AtoP_high_v05,AtoP_high_v06,AtoP_high_v07
  257.         .dc.l        AtoP_high_v08,AtoP_high_v09,AtoP_high_v10,AtoP_high_v11
  258.         .dc.l        AtoP_high_v12,AtoP_high_v13,AtoP_high_v14,AtoP_high_v15
  259.         .dc.l        AtoP_high_vnn,AtoP_high_non
  260.  
  261. AtoP_low_tbl:    .dc.l        AtoP_low_v00,AtoP_low_v01,AtoP_low_v02,AtoP_low_v03
  262.         .dc.l        AtoP_low_v04,AtoP_low_v05,AtoP_low_v06,AtoP_low_v07
  263.         .dc.l        AtoP_low_v08,AtoP_low_v09,AtoP_low_v10,AtoP_low_v11
  264.         .dc.l        AtoP_low_v12,AtoP_low_v13,AtoP_low_v14,AtoP_low_v15
  265.         .dc.l        AtoP_low_vnn,AtoP_low_non
  266.  
  267. AtoP_0101_tbl:    .dc.l        AtoP_0101_v00,AtoP_0101_v01,AtoP_0101_v02,AtoP_0101_v03
  268.         .dc.l        AtoP_0101_v04,AtoP_0101_v05,AtoP_0101_v06,AtoP_0101_v07
  269.         .dc.l        AtoP_0101_v08,AtoP_0101_v09,AtoP_0101_v10,AtoP_0101_v11
  270.         .dc.l        AtoP_0101_v12,AtoP_0101_v13,AtoP_0101_v14,AtoP_0101_v15
  271.         .dc.l        AtoP_0101_vnn,AtoP_0101_non
  272.  
  273. AtoP_0203_tbl:    .dc.l        AtoP_0203_v00,AtoP_0203_v01,AtoP_0203_v02,AtoP_0203_v03
  274.         .dc.l        AtoP_0203_v04,AtoP_0203_v05,AtoP_0203_v06,AtoP_0203_v07
  275.         .dc.l        AtoP_0203_v08,AtoP_0203_v09,AtoP_0203_v10,AtoP_0203_v11
  276.         .dc.l        AtoP_0203_v12,AtoP_0203_v13,AtoP_0203_v14,AtoP_0203_v15
  277.         .dc.l        AtoP_0203_vnn,AtoP_0203_non
  278.  
  279. AtoP_0102_tbl:    .dc.l        AtoP_0102_v00,AtoP_0102_v01,AtoP_0102_v02,AtoP_0102_v03
  280.         .dc.l        AtoP_0102_v04,AtoP_0102_v05,AtoP_0102_v06,AtoP_0102_v07
  281.         .dc.l        AtoP_0102_v08,AtoP_0102_v09,AtoP_0102_v10,AtoP_0102_v11
  282.         .dc.l        AtoP_0102_v12,AtoP_0102_v13,AtoP_0102_v14,AtoP_0102_v15
  283.         .dc.l        AtoP_0102_vnn,AtoP_0102_non
  284.  
  285. AtoP_0103_tbl:    .dc.l        AtoP_0103_v00,AtoP_0103_v01,AtoP_0103_v02,AtoP_0103_v03
  286.         .dc.l        AtoP_0103_v04,AtoP_0103_v05,AtoP_0103_v06,AtoP_0103_v07
  287.         .dc.l        AtoP_0103_v08,AtoP_0103_v09,AtoP_0103_v10,AtoP_0103_v11
  288.         .dc.l        AtoP_0103_v12,AtoP_0103_v13,AtoP_0103_v14,AtoP_0103_v15
  289.         .dc.l        AtoP_0103_vnn,AtoP_0103_non
  290.  
  291. AtoP_0104_tbl:    .dc.l        AtoP_0104_v00,AtoP_0104_v01,AtoP_0104_v02,AtoP_0104_v03
  292.         .dc.l        AtoP_0104_v04,AtoP_0104_v05,AtoP_0104_v06,AtoP_0104_v07
  293.         .dc.l        AtoP_0104_v08,AtoP_0104_v09,AtoP_0104_v10,AtoP_0104_v11
  294.         .dc.l        AtoP_0104_v12,AtoP_0104_v13,AtoP_0104_v14,AtoP_0104_v15
  295.         .dc.l        AtoP_0104_vnn,AtoP_0104_non
  296.  
  297. PCM16_high_tbl:    .dc.l        PCM16_high_v00,PCM16_high_v01,PCM16_high_v02,PCM16_high_v03
  298.         .dc.l        PCM16_high_v04,PCM16_high_v05,PCM16_high_v06,PCM16_high_v07
  299.         .dc.l        PCM16_high_v08,PCM16_high_v09,PCM16_high_v10,PCM16_high_v11
  300.         .dc.l        PCM16_high_v12,PCM16_high_v13,PCM16_high_v14,PCM16_high_v15
  301.         .dc.l        PCM16_high_vnn,PCM16_high_non
  302.  
  303. PCM16_low_tbl:    .dc.l        PCM16_low_v00,PCM16_low_v01,PCM16_low_v02,PCM16_low_v03
  304.         .dc.l        PCM16_low_v04,PCM16_low_v05,PCM16_low_v06,PCM16_low_v07
  305.         .dc.l        PCM16_low_v08,PCM16_low_v09,PCM16_low_v10,PCM16_low_v11
  306.         .dc.l        PCM16_low_v12,PCM16_low_v13,PCM16_low_v14,PCM16_low_v15
  307.         .dc.l        PCM16_low_vnn,PCM16_low_non
  308.  
  309. PCM16_0101_tbl:.dc.l        PCM16_0101_v00,PCM16_0101_v01,PCM16_0101_v02,PCM16_0101_v03
  310.         .dc.l        PCM16_0101_v04,PCM16_0101_v05,PCM16_0101_v06,PCM16_0101_v07
  311.         .dc.l        PCM16_0101_v08,PCM16_0101_v09,PCM16_0101_v10,PCM16_0101_v11
  312.         .dc.l        PCM16_0101_v12,PCM16_0101_v13,PCM16_0101_v14,PCM16_0101_v15
  313.         .dc.l        PCM16_0101_vnn,PCM16_0101_non
  314.  
  315. PCM16_0203_tbl:.dc.l        PCM16_0203_v00,PCM16_0203_v01,PCM16_0203_v02,PCM16_0203_v03
  316.         .dc.l        PCM16_0203_v04,PCM16_0203_v05,PCM16_0203_v06,PCM16_0203_v07
  317.         .dc.l        PCM16_0203_v08,PCM16_0203_v09,PCM16_0203_v10,PCM16_0203_v11
  318.         .dc.l        PCM16_0203_v12,PCM16_0203_v13,PCM16_0203_v14,PCM16_0203_v15
  319.         .dc.l        PCM16_0203_vnn,PCM16_0203_non
  320.  
  321. PCM16_0102_tbl:    .dc.l        PCM16_0102_v00,PCM16_0102_v01,PCM16_0102_v02,PCM16_0102_v03
  322.         .dc.l        PCM16_0102_v04,PCM16_0102_v05,PCM16_0102_v06,PCM16_0102_v07
  323.         .dc.l        PCM16_0102_v08,PCM16_0102_v09,PCM16_0102_v10,PCM16_0102_v11
  324.         .dc.l        PCM16_0102_v12,PCM16_0102_v13,PCM16_0102_v14,PCM16_0102_v15
  325.         .dc.l        PCM16_0102_vnn,PCM16_0102_non
  326.  
  327. PCM16_0103_tbl:    .dc.l        PCM16_0103_v00,PCM16_0103_v01,PCM16_0103_v02,PCM16_0103_v03
  328.         .dc.l        PCM16_0103_v04,PCM16_0103_v05,PCM16_0103_v06,PCM16_0103_v07
  329.         .dc.l        PCM16_0103_v08,PCM16_0103_v09,PCM16_0103_v10,PCM16_0103_v11
  330.         .dc.l        PCM16_0103_v12,PCM16_0103_v13,PCM16_0103_v14,PCM16_0103_v15
  331.         .dc.l        PCM16_0103_vnn,PCM16_0103_non
  332.  
  333. PCM16_0104_tbl:    .dc.l        PCM16_0104_v00,PCM16_0104_v01,PCM16_0104_v02,PCM16_0104_v03
  334.         .dc.l        PCM16_0104_v04,PCM16_0104_v05,PCM16_0104_v06,PCM16_0104_v07
  335.         .dc.l        PCM16_0104_v08,PCM16_0104_v09,PCM16_0104_v10,PCM16_0104_v11
  336.         .dc.l        PCM16_0104_v12,PCM16_0104_v13,PCM16_0104_v14,PCM16_0104_v15
  337.         .dc.l        PCM16_0104_vnn,PCM16_0104_non
  338.  
  339. PCM8_high_tbl:    .dc.l        PCM8_high_v00,PCM8_high_v01,PCM8_high_v02,PCM8_high_v03
  340.         .dc.l        PCM8_high_v04,PCM8_high_v05,PCM8_high_v06,PCM8_high_v07
  341.         .dc.l        PCM8_high_v08,PCM8_high_v09,PCM8_high_v10,PCM8_high_v11
  342.         .dc.l        PCM8_high_v12,PCM8_high_v13,PCM8_high_v14,PCM8_high_v15
  343.         .dc.l        PCM8_high_vnn,PCM8_high_non
  344.  
  345. PCM8_low_tbl:    .dc.l        PCM8_low_v00,PCM8_low_v01,PCM8_low_v02,PCM8_low_v03
  346.         .dc.l        PCM8_low_v04,PCM8_low_v05,PCM8_low_v06,PCM8_low_v07
  347.         .dc.l        PCM8_low_v08,PCM8_low_v09,PCM8_low_v10,PCM8_low_v11
  348.         .dc.l        PCM8_low_v12,PCM8_low_v13,PCM8_low_v14,PCM8_low_v15
  349.         .dc.l        PCM8_low_vnn,PCM8_low_non
  350.  
  351. PCM8_0101_tbl:    .dc.l        PCM8_0101_v00,PCM8_0101_v01,PCM8_0101_v02,PCM8_0101_v03
  352.         .dc.l        PCM8_0101_v04,PCM8_0101_v05,PCM8_0101_v06,PCM8_0101_v07
  353.         .dc.l        PCM8_0101_v08,PCM8_0101_v09,PCM8_0101_v10,PCM8_0101_v11
  354.         .dc.l        PCM8_0101_v12,PCM8_0101_v13,PCM8_0101_v14,PCM8_0101_v15
  355.         .dc.l        PCM8_0101_vnn,PCM8_0101_non
  356.  
  357. PCM8_0203_tbl:    .dc.l        PCM8_0203_v00,PCM8_0203_v01,PCM8_0203_v02,PCM8_0203_v03
  358.         .dc.l        PCM8_0203_v04,PCM8_0203_v05,PCM8_0203_v06,PCM8_0203_v07
  359.         .dc.l        PCM8_0203_v08,PCM8_0203_v09,PCM8_0203_v10,PCM8_0203_v11
  360.         .dc.l        PCM8_0203_v12,PCM8_0203_v13,PCM8_0203_v14,PCM8_0203_v15
  361.         .dc.l        PCM8_0203_vnn,PCM8_0203_non
  362.  
  363. PCM8_0102_tbl:    .dc.l        PCM8_0102_v00,PCM8_0102_v01,PCM8_0102_v02,PCM8_0102_v03
  364.         .dc.l        PCM8_0102_v04,PCM8_0102_v05,PCM8_0102_v06,PCM8_0102_v07
  365.         .dc.l        PCM8_0102_v08,PCM8_0102_v09,PCM8_0102_v10,PCM8_0102_v11
  366.         .dc.l        PCM8_0102_v12,PCM8_0102_v13,PCM8_0102_v14,PCM8_0102_v15
  367.         .dc.l        PCM8_0102_vnn,PCM8_0102_non
  368.  
  369. PCM8_0103_tbl:    .dc.l        PCM8_0103_v00,PCM8_0103_v01,PCM8_0103_v02,PCM8_0103_v03
  370.         .dc.l        PCM8_0103_v04,PCM8_0103_v05,PCM8_0103_v06,PCM8_0103_v07
  371.         .dc.l        PCM8_0103_v08,PCM8_0103_v09,PCM8_0103_v10,PCM8_0103_v11
  372.         .dc.l        PCM8_0103_v12,PCM8_0103_v13,PCM8_0103_v14,PCM8_0103_v15
  373.         .dc.l        PCM8_0103_vnn,PCM8_0103_non
  374.  
  375. PCM8_0104_tbl:    .dc.l        PCM8_0104_v00,PCM8_0104_v01,PCM8_0104_v02,PCM8_0104_v03
  376.         .dc.l        PCM8_0104_v04,PCM8_0104_v05,PCM8_0104_v06,PCM8_0104_v07
  377.         .dc.l        PCM8_0104_v08,PCM8_0104_v09,PCM8_0104_v10,PCM8_0104_v11
  378.         .dc.l        PCM8_0104_v12,PCM8_0104_v13,PCM8_0104_v14,PCM8_0104_v15
  379.         .dc.l        PCM8_0104_vnn,PCM8_0104_non
  380.  
  381.  
  382. *▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
  383. *
  384. *        ファンクションコール TRAP #1 処理
  385. *
  386. *△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△
  387.  
  388.  
  389.         .dc.b        'MPCM/040'
  390. mpcm_trap1:    addi.w        #1,trap1_nest
  391.         bgt        trap1_nested        * trap#1 処理中に再び呼び出された
  392.         movem.l        d1-d7/a0-a6,-(sp)
  393.  
  394.         lea.l        mpw(pc),a6        * a6.l = trap#1用ワーク先頭アドレス
  395.  
  396. .ifdef    FCTRACE
  397.         movea.l        fc_logadr-mpw(a6),a0
  398.         move.w        d0,(a0)+
  399.         move.l        a0,fc_logadr-mpw(a6)
  400. .endif
  401.  
  402.         tst.w        d0            * $8000 <= d0.w ?
  403.         bmi        special_func        * MPCM制御
  404.         cmpi.w        #$1000,d0
  405.         bcc        effect_func        * 効果音制御
  406.  
  407. normal_func:    cmpi.b        #$ff,d0
  408.         beq        normal_func_all        * 全チャンネル指定
  409.         cmpi.w        #$07FF+1,d0
  410.         bcc        func_error        * ファンクション番号異常
  411.  
  412.         moveq.l        #0,d7
  413.         move.b        d0,d7            * d7.w = チャンネル番号
  414.         cmpi.w        #CH_MAX,d7
  415.         bcc        func_error        * チャンネル番号チェック
  416.  
  417.         lsl.w        #7,d7            * CH * CH_WORK_SIZE(128)
  418.         lea.l        ch0_work(pc),a5
  419.         adda.w        d7,a5            * a5.l = 各チャンネルワークのアドレス
  420.  
  421.         clr.b        d0            * 下位8bit殺す
  422.         lsr.w        #6,d0
  423.         move.l        trap1_jmp_tbl0(pc,d0.w),a0
  424.         pea.l        trap1_ret(pc)
  425.         jmp        (a0)            * 各ファンクションへ
  426.  
  427. normal_func_all:cmpi.w        #$07FF+1,d0
  428.         bcc        func_error        * ファンクション番号異常
  429.  
  430.         clr.b        d0            * 下位8bit殺す
  431.         lsr.w        #6,d0
  432.         move.l        trap1_jmp_tbl0(pc,d0.w),a0    * a0.l = ファンクションアドレス
  433.         lea.l        ch0_work+CH_WORK_SIZE*(CH_MAX-1)(pc),a5
  434.         moveq.l        #CH_MAX-1,d0        * 全チャンネル指定
  435. @@:        movem.l        d0-d6/a0-a4,-(sp)
  436.         jsr        (a0)
  437.         movem.l        (sp)+,d0-d6/a0-a4
  438.         lea.l        -CH_WORK_SIZE(a5),a5
  439.         dbra        d0,@b
  440.         bra        trap1_ret        * 終了
  441.  
  442.  
  443. trap1_jmp_tbl0:    .dc.l        func_00xx        * PCM KEY ON
  444.         .dc.l        func_01xx        * PCM KEY OFF
  445.         .dc.l        func_02xx        * PCM データ登録
  446.         .dc.l        func_03xx        * PCM 再生周波数設定
  447.         .dc.l        func_04xx        * PCM 音程設定
  448.         .dc.l        func_05xx        * PCM 音量設定
  449.         .dc.l        func_06xx        * PCM PAN設定
  450.         .dc.l        func_07xx        * PCM 種類変更
  451.  
  452.  
  453. effect_func:    cmpi.b        #$ff,d0
  454.         beq        effect_func_all        * 全チャンネル指定
  455.         cmpi.b        #$e0,d0
  456.         bcc        effect_func_free    * 空きチャンネル
  457.  
  458.         cmpi.w        #$13FF+1,d0
  459.         bcc        func_error        * ファンクション番号異常
  460.         moveq.l        #0,d7
  461.         move.b        d0,d7            * d7.w = チャンネル番号
  462.         cmpi.w        #EFCT_MAX,d7
  463.         bcc        func_error        * チャンネル番号チェック
  464.  
  465.         lsl.w        #6,d7            * CH * EFCT_WORK_SIZE(64)
  466.         lea.l        efct0_work(pc),a5
  467.         adda.w        d7,a5            * a5.l = 各チャンネルワークのアドレス
  468.  
  469.         clr.b        d0            * 下位8bit殺す
  470.         subi.w        #$1000,d0        * 上位から$1000を引く
  471.         lsr.w        #6,d0
  472. *        move.l        trap1_jmp_tbl1(pc,d0.w),a0    * rerative err!!
  473.         lea.l        trap1_jmp_tbl1(pc),a0
  474.         move.l        (a0,d0.w),a0
  475.         pea.l        trap1_ret(pc)
  476.         jmp        (a0)            * 各ファンクションへ
  477.  
  478. effect_func_free:
  479.         cmpi.w        #$13FF+1,d0
  480.         bcc        func_error        * ファンクション番号異常
  481.  
  482.         lea.l        efct0_work(pc),a5
  483.         move.w        efct_poly-mpw(a6),d7    * 効果音ポリフォニック数
  484.         bmi        func_error        * -1 は発音無し
  485.  
  486.         move.l        a5,a0
  487.         move.w        d7,d5
  488.         move.l        EFCT_PCM_LEN(a0),d6    * 一番残りが短いやつを探す
  489. 1:        tst.b        EFCT_PLAY_FLAG(a5)
  490.         beq        3f            * 空いていた!
  491.         cmp.l        EFCT_PCM_LEN(a5),d6
  492.         bmi        2f
  493.         movea.l        a5,a0
  494.         move.w        d7,d5
  495.         move.l        EFCT_PCM_LEN(a0),d6    * 現在のやつが一番短い
  496. 2:        lea.l        EFCT_WORK_SIZE(a5),a5
  497.         dbra        d7,1b
  498.  
  499.         * 空きがない処理
  500.  
  501.         movea.l        a0,a5            * 再生データの残りが一番少ないチャンネル
  502.         move.w        d5,d7
  503.  
  504.         * 空きがあった時
  505. 3:        move.l        d7,-(sp)        * 使用チャンネル番号保存
  506.         clr.b        d0            * 下位8bit殺す
  507.         subi.w        #$1000,d0
  508.         lsr.w        #6,d0
  509.         move.l        trap1_jmp_tbl1(pc,d0.w),a0
  510.         jsr        (a0)            * 各ファンクションへ
  511.         move.l        (sp)+,d0        * 使用チャンネル番号復帰
  512.         bra        trap1_ret
  513.  
  514. effect_func_all:cmpi.w        #$13FF+1,d0
  515.         bcc        func_error        * ファンクション番号異常
  516.  
  517.         clr.b        d0            * 下位8bit殺す
  518.         subi.w        #$1000,d0
  519.         lsr.w        #6,d0
  520.  
  521.         move.l        trap1_jmp_tbl1(pc,d0.w),a0    * a0.l = ファンクションアドレス
  522.         lea.l        efct0_work(pc),a5
  523.         move.w        #EFCT_MAX-1,d0        * 全チャンネル指定
  524. @@:        movem.l        d0-d6/a0-a4,-(sp)
  525.         jsr        (a0)
  526.         movem.l        (sp)+,d0-d6/a0-a4
  527.         lea.l        EFCT_WORK_SIZE(a5),a5
  528.         dbra        d0,@b
  529.         bra        trap1_ret        * 終了
  530.  
  531. trap1_jmp_tbl1:    .dc.l        func_10xx        * 効果音再生
  532.         .dc.l        reserved
  533.         .dc.l        reserved
  534.         .dc.l        func_13xx        * 効果音停止
  535.  
  536.  
  537. special_func:    cmpi.w        #$8013+1,d0
  538.         bcc        func_error        * そんなファンクション番号はないよ
  539.         add.w        d0,d0
  540.         add.w        d0,d0
  541.         move.l        trap1_jmp_tbl2(pc,d0.w),a0
  542.         pea.l        trap1_ret(pc)
  543.         jmp        (a0)
  544.  
  545. trap1_jmp_tbl2:    .dc.l        func_8000        * 占有する
  546.         .dc.l        func_8001        * 占有を解除する
  547.         .dc.l        func_8002        * 初期化
  548.         .dc.l        func_8003        * 割り込みマスク設定
  549.         .dc.l        func_8004        * MPCM動作モード設定
  550.         .dc.l        func_8005        * 音量マップ設定
  551.         .dc.l        func_8006        * 効果音チャンネル最大数設定
  552.         .dc.l        reserved
  553.         .dc.l        reserved
  554.         .dc.l        reserved
  555.         .dc.l        reserved
  556.         .dc.l        reserved
  557.         .dc.l        reserved
  558.         .dc.l        reserved
  559.         .dc.l        reserved
  560.         .dc.l        reserved
  561.         .dc.l        func_8010        * チャンネルワークアドレス収得
  562.         .dc.l        func_8011        * システムワークアドレス収得
  563.         .dc.l        func_8012        * チャンネル別処理アドレス収得
  564.         .dc.l        func_8013        * 全体処理アドレス収得
  565.  
  566. reserved:
  567. func_error:    moveq.l        #-1,d0
  568. trap1_ret:    movem.l        (sp)+,d1-d7/a0-a6
  569. trap1_nested:    sub.w        #1,trap1_nest
  570.         rte
  571.  
  572. *===============================================================
  573. * func_00xx    : PCM KEY ON
  574. * call        : a5.l    = チャンネルワークアドレス
  575. * return    : d0.l    ≧ 0    : 正常終了
  576. *              < 0    : 録音中でKEY ON できない
  577. *===============================================================
  578.  
  579. func_00xx:    btst.b        #2,ADPCM_SYSWORK.w    * 録音中?
  580.         beq        @f
  581.         moveq.l        #-1,d0
  582.         rts                    * ならキーオンしない
  583.  
  584. @@:        move.b        #$01,CH_KEY_STAT(a5)    * キーオン
  585.         st.b        CH_PLAY_FLAG(a5)    * 演奏中
  586.  
  587.         tst.l        play_flag-mpw(a6)
  588.         beq        func_00xx_DMA_start
  589.         moveq.l        #0,d0
  590.         rts
  591.  
  592. func_00xx_DMA_start:
  593.         lea.l        DMA3,a0
  594.         move.b        #$10,DCCR(a0)        * CCR DMA停止割り込み無し
  595.  
  596.         move.l        #PtoA_tbl,PtoA_X-mpw(a6)    * PCM -> ADPCM ワーク初期化
  597.         clr.w        PtoA_Y-mpw(a6)
  598.         st.b        ADPCM_out_flag-mpw(a6)
  599.  
  600.         move.w        #$8002,DCR(a0)        * 初期演奏は空演奏
  601.         move.b        #$04,SCR(a0)
  602.         move.b        #$01,CPR(a0)
  603.  
  604.         moveq.l        #MIX_SIZE,d1
  605.         moveq.l        #5,d2
  606.         lea.l        dummy_ADPCM-mpw(a6),a1
  607.  
  608.         move.l        #ADPCM+3,DAR(a0)    * ADPCM データレジスタ
  609.         move.b        d2,DFC(a0)        * move.b #$05,DFC(a0)
  610.  
  611.         move.w        d1,MTC(a0)        * $88+$80を1回分転送
  612.         move.b        d2,MFC(a0)
  613.         move.l        a1,MAR(a0)
  614.  
  615.         move.w        d1,BTC(a0)        * $88+$80をもう1回分転送
  616.         move.b        d2,BFC(a0)
  617.         move.l        a1,BAR(a0)
  618.  
  619.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  620.         move.b        #$c8,DCCR(a0)        * 動作開始/継続モード/転送終了割込あり
  621.  
  622.         move.b        #$02,ADPCM+1        * ADPCM play start(念のため)
  623.         rts
  624.  
  625. *===============================================================
  626. * func_01xx    : PCM KEY OFF
  627. * call        : a5.l = チャンネルワークアドレス
  628. * return    : d0.l ≧ 0            : 正常終了
  629. *===============================================================
  630.  
  631. func_01xx:    st.b        CH_KEY_STAT(a5)        * key off
  632.         moveq.l        #0,d0
  633.         rts
  634.  
  635. *===============================================================
  636. * func_02xx    : PCM データ登録
  637. * call        : d1.l = 0 (将来拡張用)
  638. *          a1.l = PCM情報テーブルアドレス
  639. *            $0000(a1).b = PCM種類(-1:ADPCM 0:データ無し 1:16bitPCM 2:8bitPCM)
  640. *            $0001(a1).b = PCMのオリジナルノート番号(0~127,負の場合は原音程固定再生)
  641. *            $0002-$0003(a1).b = 何でもよい
  642. *            $0004(a1).l = PCMアドレス(絶対番地)
  643. *            $0008(a1).l = PCMの長さ
  644. *            $000c(a1).l = ループ開始点オフセット
  645. *            $0010(a1).l = ループ終了点オフセット
  646. *            $0014(a1).l = ループ回数(0で無限ループ、通常は1)
  647. *          a5.l = チャンネルワークアドレス
  648. * return    : d0.l ≧ 0        : 正常終了
  649. *                < 0        : 登録失敗
  650. *               原因としては、16bitPCM登録時に、
  651. *               アドレス、長さ、ループポインタのいずれかが奇数である、などなど
  652. *===============================================================
  653.  
  654. func_02xx:
  655.         move.b        (a1)+,d1        * PCM種類
  656.         beq        f02xx_noPCM        *  0: データ無し
  657.  
  658.         moveq.l        #0,d2
  659.         move.b        (a1)+,d2        * オリジナルノート
  660.         lsl.w        #6,d2            * 64倍
  661.         addq.l        #2,a1            * アドレス補正
  662.         move.b        d1,CH_PCM_KIND(a5)    * PCM種類登録
  663.         bmi        f02xx_ADPCM        * -1: ADPCM
  664.         subq.b        #2,d1            
  665.         bmi        f02xx_PCM16        *  1: 16bit PCM
  666.         beq        f02xx_PCM8        *  2: 8bit PCM
  667.  
  668. func_02xx_err:    clr.b        CH_PLAY_FLAG(a6)    * 演奏中止
  669.         clr.b        CH_KEY_STAT(a6)        * non
  670. *        clr.b        CH_PCM_KIND(a5)        * PCM種類 = none
  671.         moveq.l        #-1,d0            * 種類がおかしいよ!
  672.         bra        f02xx_noPCMxx        * 演奏しない
  673.  
  674. *         ADPCM 登録
  675.  
  676. f02xx_ADPCM:    clr.b        CH_PLAY_FLAG(a6)    * 演奏中止
  677.         clr.b        CH_KEY_STAT(a6)
  678.         move.w        d2,CH_ORG_NOTE(a5)    * オリジナルノート登録
  679.         move.w        d2,CH_USER_NOTE(a5)    * ユーザー指定ノートも書きかえる
  680.         movea.l        (a1)+,a0        * a0.l = ADPCM先頭アドレス
  681.         move.l        a0,CH_TOP_ADR(a5)
  682.         move.l        (a1)+,d2        * ADPCM長さ
  683.         add.l        a0,d2            * d2.l = ADPCM終了アドレス+1を差す
  684.         move.l        d2,CH_END_ADR(a5)
  685.         move.l        (a1)+,d2        * ループ先頭オフセット
  686.         add.l        a0,d2            * d2.l = ループ先頭アドレスを差す
  687.         move.l        d2,CH_LPSTART_ADR(a5)
  688.         addq.l        #1,a0            * ループ終端オフセット
  689.         adda.l        (a1)+,a0        * a0.l = ループ終端アドレス+1を差す
  690.         move.l        a0,CH_LPEND_ADR(a5)
  691.         move.l        (a1)+,CH_LPTIME(a5)    *  ループ回数(0で無限ループ)
  692.         move.l        #CALC_TPCNSTADP,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  693.  
  694.         move.w        CH_USER_NOTE(a5),d1
  695.         bra        func_04xx_x        * 音程再設定
  696.  
  697. *        16bitPCM 登録
  698.  
  699. f02xx_PCM16:    clr.b        CH_PLAY_FLAG(a6)    * 演奏中止
  700.         clr.b        CH_KEY_STAT(a6)
  701.         move.w        d2,CH_ORG_NOTE(a5)    * オリジナルノート登録
  702. *        move.w        d2,CH_USER_NOTE(a5)    * ユーザー指定ノートも書きかえる
  703.         move.l        (a1)+,d3        * d3.l = 16bitPCM 先頭アドレス
  704.         btst.l        #0,d3
  705.         bne        func_02xx_err        * 偶数じゃないぞ
  706.         move.l        d3,CH_TOP_ADR(a5)
  707.         move.l        (a1)+,d2        * 16bitPCM長さ
  708.         add.l        d3,d2            * d2.l = 終了アドレス+1を差す
  709.         btst.l        #0,d2
  710.         bne        func_02xx_err        * 偶数じゃないぞ
  711.         move.l        d2,CH_END_ADR(a5)
  712.         move.l        (a1)+,d2        * ループ先頭オフセット
  713.         add.l        d3,d2            * d2.l = ループ先頭アドレスを差す
  714.         btst.l        #0,d2
  715.         bne        func_02xx_err        * 偶数じゃないぞ
  716.         move.l        d2,CH_LPSTART_ADR(a5)
  717.         move.l        (a1)+,d2        * ループ終端オフセット
  718.         addq.l        #2,d2            * 16bitPCMだから2足す
  719.         add.l        d3,d2            * d2.l = ループ終端アドレス+2を差す
  720.         btst.l        #0,d2
  721.         bne        func_02xx_err        * 偶数じゃないぞ
  722.         move.l        d2,CH_LPEND_ADR(a5)
  723.         move.l        (a1)+,CH_LPTIME(a5)    * ループ回数(0で無限ループ)
  724.         move.l        #CALC_TPCNST16,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  725.  
  726.         move.w        CH_USER_NOTE(a5),d1
  727.         bra        func_04xx_x        * 音程再設定
  728.  
  729. *        8bitPCM 登録
  730.  
  731. f02xx_PCM8:    clr.b        CH_PLAY_FLAG(a6)    * 演奏中止
  732.         clr.b        CH_KEY_STAT(a6)
  733.         move.w        d2,CH_ORG_NOTE(a5)    * オリジナルノート登録
  734. *        move.w        d2,CH_USER_NOTE(a5)    * ユーザー指定ノートも書きかえる
  735.         movea.l        (a1)+,a0        * a0.l = 8bitPCM先頭アドレス
  736.         move.l        a0,CH_TOP_ADR(a5)
  737.         move.l        (a1)+,d2        * 8bitPCM長さ
  738.         add.l        a0,d2            * d2.l = 終了アドレス+1 を差す
  739.         move.l        d2,CH_END_ADR(a5)
  740.         move.l        (a1)+,d2        * ループ先頭オフセット
  741.         add.l        a0,d2            * d2.l = ループ先頭アドレスを差す
  742.         move.l        d2,CH_LPSTART_ADR(a5)
  743.         addq.l        #1,a0            * ループ終端オフセット
  744.         adda.l        (a1)+,a0        * a0.l = ループ終端アドレス+1を差す
  745.         move.l        a0,CH_LPEND_ADR(a5)
  746.         move.l        (a1)+,CH_LPTIME(a5)    * ループ回数(0で無限ループ)
  747.         move.l        #CALC_TPCNST8,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  748.  
  749.         move.w        CH_USER_NOTE(a5),d1
  750.         bra        func_04xx_x        * 音程再設定
  751.  
  752. *        データ無し
  753.  
  754. f02xx_noPCM:    moveq.l        #0,d0            * 戻り値(正常)
  755. f02xx_noPCMxx:    clr.b        CH_PLAY_FLAG(a5)    * 演奏中止(KEY OFFではない)
  756.         clr.b        CH_KEY_STAT(a5)        * KEY OFF状態
  757.         move.l        #CALC_TPCNSTNO,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  758.         move.l        #NO_PCM,CH_JMP_ADR(a5)    * データ無しの場合
  759.         rts
  760.  
  761. *===============================================================
  762. * func_03xx    : PCM 再生周波数指定
  763. * call        : d1.w = 再生周波数
  764. *             0 =  3.9kHz
  765. *             1 =  5.2kHz
  766. *             2 =  7.8kHz
  767. *             3 = 10.4kHz
  768. *             4 = 15.6kHz
  769. *             5 = 20.8kHz
  770. *             6 = 31.2kHz
  771. *          a5.l = チャンネルワークアドレス
  772. * return    : d0.l ≧ 0    正常終了
  773. *                      < 0     異状終了
  774. *===============================================================
  775.  
  776. func_03xx:    cmp.b        CH_USER_FRQ(a5),d1
  777.         bne        @f
  778.         rts                        * 変わらなかったら何もしない
  779. @@:        cmpi.w        #$0006+1,d1
  780.         bcc        @f                * エラーだ
  781.         move.b        d1,CH_USER_FRQ(a5)        * ユーザーが指定した値を保存
  782.         add.w        d1,d1
  783.         add.w        d1,d1
  784.         add.w        frq_offset-mpw(a6),d1    * PCM高音質化対応
  785.         movea.l        func_03xx_tbl(pc,d1.w),a0
  786.         move.l        a0,CH_PITCH_CADR(a5)
  787.         move.l        CH_ORG_PITCH(a5),d1        * オリジナルのピッチを再変換
  788.         jmp        (a0)                * 音程再設定
  789.  
  790. @@:        moveq.l        #-1,d0
  791.         rts
  792.  
  793. func_03xx_tbl:
  794.         .dc.l        func_04xx_01_08        * PITCH *  1/ 8
  795.         .dc.l        func_04xx_01_06        * PITCH *  1/ 6
  796.         .dc.l        func_04xx_01_04        * PITCH *  1/ 4
  797.         .dc.l        func_04xx_01_03        * PITCH *  1/ 3
  798.         .dc.l        func_04xx_01_02        * PITCH *  1/ 2
  799.         .dc.l        func_04xx_02_03        * PITCH *  2/ 3
  800.         .dc.l        func_04xx_01_01        * PITCH *  1/ 1
  801.         .dc.l        func_04xx_04_03        * PITCH *  4/ 3
  802.         .dc.l        func_04xx_02_01        * PITCH *  2/ 1
  803.         .dc.l        func_04xx_08_03        * PITCH *  8/ 3
  804.         .dc.l        func_04xx_04_01        * PITCH *  4/ 1
  805.  
  806. *===============================================================
  807. * func_04xx    : PCM 音程設定
  808. * call        : d1.w = 音程
  809. *             0~127(ノート番号)*64+0~63(ディチューン)
  810. *             FM音源と同じ考え(4倍はしなくてよい)
  811. *          a5.l = チャンネルワークアドレス
  812. * return    : d0.l ≧ 0    正常終了
  813. *               < 0    エラー(音程が範囲外、など)
  814. *          special thanks to Z.Nisikawa
  815. *===============================================================
  816.  
  817. func_04xx:
  818.         cmpi.w        #127*64+63+1,d1
  819.         bcs        @f        
  820.         moveq.l        #-1,d0            * 範囲外
  821.         rts
  822.  
  823. @@:        move.w        d1,CH_USER_NOTE(a5)    * ユーザー指定のノート保存
  824. func_04xx_x:    move.w        CH_ORG_NOTE(a5),d0
  825.         cmpi.w        #$1fc0+1,d0        * オリジナルキーが負?
  826.         bcs        @f
  827.         moveq.l        #1,d1
  828.         swap.w        d1
  829.         move.l        d1,CH_ORG_PITCH(a5)    * 原音程固定
  830.         movea.l        CH_PITCH_CADR(a5),a0
  831.         jmp        (a0)
  832.  
  833. @@:        sub.w        d0,d1
  834.         bmi        @f
  835.  
  836.         moveq.l        #0,d0
  837. 1:        subi.w        #64*12,d1
  838.         bcs        2f
  839.         addq.l        #1,d0
  840.         bra        1b
  841. 2:        addi.w        #64*12,d1        * d0.l = オクターブの差
  842.         add.w        d1,d1            * d1.w = ノートの差
  843.         moveq.l        #1,d2
  844.         swap.w        d2
  845.         move.w        f04_pitch_tbl(pc,d1.w),d2
  846.         lsl.l        d0,d2            * 左シフト
  847.         move.l        d2,CH_ORG_PITCH(a5)    * 周波数変換前のピッチ
  848.         move.l        d2,d1
  849.         movea.l        CH_PITCH_CADR(a5),a0
  850.         jmp        (a0)
  851.  
  852. @@:        moveq.l        #0,d0
  853. 1:        addi.w        #64*12,d1
  854.         bcs        2f
  855.         addq.l        #1,d0
  856.         bra        1b
  857. 2:        addq.l        #1,d0            * d0.l = オクターブの差
  858.         add.w        d1,d1
  859.         moveq.l        #1,d2            * d1.w = ノートの差
  860.         swap.w        d2
  861.         move.w        f04_pitch_tbl(pc,d1.w),d2
  862.         lsr.l        d0,d2            * 右シフト
  863.         move.l        d2,CH_ORG_PITCH(a5)
  864.         movea.l        CH_PITCH_CADR(a5),a0
  865.         move.l        d2,d1
  866.         jmp        (a0)
  867.  
  868. f04_pitch_tbl:                        * PCMの1オクターブ分の変化テーブル
  869.                     *for i=0 to 768-1:print (2^(i/768)*65536-65536):next
  870.         .dc.w        $0000,$003b,$0076,$00b2,$00ed,$0128,$0164,$019f
  871.         .dc.w        $01db,$0217,$0252,$028e,$02ca,$0305,$0341,$037d
  872.         .dc.w        $03b9,$03f5,$0431,$046e,$04aa,$04e6,$0522,$055f
  873.         .dc.w        $059b,$05d8,$0614,$0651,$068d,$06ca,$0707,$0743
  874.         .dc.w        $0780,$07bd,$07fa,$0837,$0874,$08b1,$08ef,$092c
  875.         .dc.w        $0969,$09a7,$09e4,$0a21,$0a5f,$0a9c,$0ada,$0b18
  876.         .dc.w        $0b56,$0b93,$0bd1,$0c0f,$0c4d,$0c8b,$0cc9,$0d07
  877.         .dc.w        $0d45,$0d84,$0dc2,$0e00,$0e3f,$0e7d,$0ebc,$0efa
  878.         .dc.w        $0f39,$0f78,$0fb6,$0ff5,$1034,$1073,$10b2,$10f1
  879.         .dc.w        $1130,$116f,$11ae,$11ee,$122d,$126c,$12ac,$12eb
  880.         .dc.w        $132b,$136b,$13aa,$13ea,$142a,$146a,$14a9,$14e9
  881.         .dc.w        $1529,$1569,$15aa,$15ea,$162a,$166a,$16ab,$16eb
  882.         .dc.w        $172c,$176c,$17ad,$17ed,$182e,$186f,$18b0,$18f0
  883.         .dc.w        $1931,$1972,$19b3,$19f5,$1a36,$1a77,$1ab8,$1afa
  884.         .dc.w        $1b3b,$1b7d,$1bbe,$1c00,$1c41,$1c83,$1cc5,$1d07
  885.         .dc.w        $1d48,$1d8a,$1dcc,$1e0e,$1e51,$1e93,$1ed5,$1f17
  886.         .dc.w        $1f5a,$1f9c,$1fdf,$2021,$2064,$20a6,$20e9,$212c
  887.         .dc.w        $216f,$21b2,$21f5,$2238,$227b,$22be,$2301,$2344
  888.         .dc.w        $2388,$23cb,$240e,$2452,$2496,$24d9,$251d,$2561
  889.         .dc.w        $25a4,$25e8,$262c,$2670,$26b4,$26f8,$273d,$2781
  890.         .dc.w        $27c5,$280a,$284e,$2892,$28d7,$291c,$2960,$29a5
  891.         .dc.w        $29ea,$2a2f,$2a74,$2ab9,$2afe,$2b43,$2b88,$2bcd
  892.         .dc.w        $2c13,$2c58,$2c9d,$2ce3,$2d28,$2d6e,$2db4,$2df9
  893.         .dc.w        $2e3f,$2e85,$2ecb,$2f11,$2f57,$2f9d,$2fe3,$302a
  894.         .dc.w        $3070,$30b6,$30fd,$3143,$318a,$31d0,$3217,$325e
  895.         .dc.w        $32a5,$32ec,$3332,$3379,$33c1,$3408,$344f,$3496
  896.         .dc.w        $34dd,$3525,$356c,$35b4,$35fb,$3643,$368b,$36d3
  897.         .dc.w        $371a,$3762,$37aa,$37f2,$383a,$3883,$38cb,$3913
  898.         .dc.w        $395c,$39a4,$39ed,$3a35,$3a7e,$3ac6,$3b0f,$3b58
  899.         .dc.w        $3ba1,$3bea,$3c33,$3c7c,$3cc5,$3d0e,$3d58,$3da1
  900.         .dc.w        $3dea,$3e34,$3e7d,$3ec7,$3f11,$3f5a,$3fa4,$3fee
  901.         .dc.w        $4038,$4082,$40cc,$4116,$4161,$41ab,$41f5,$4240
  902.         .dc.w        $428a,$42d5,$431f,$436a,$43b5,$4400,$444b,$4495
  903.         .dc.w        $44e1,$452c,$4577,$45c2,$460d,$4659,$46a4,$46f0
  904.         .dc.w        $473b,$4787,$47d3,$481e,$486a,$48b6,$4902,$494e
  905.         .dc.w        $499a,$49e6,$4a33,$4a7f,$4acb,$4b18,$4b64,$4bb1
  906.         .dc.w        $4bfe,$4c4a,$4c97,$4ce4,$4d31,$4d7e,$4dcb,$4e18
  907.         .dc.w        $4e66,$4eb3,$4f00,$4f4e,$4f9b,$4fe9,$5036,$5084
  908.         .dc.w        $50d2,$5120,$516e,$51bc,$520a,$5258,$52a6,$52f4
  909.         .dc.w        $5343,$5391,$53e0,$542e,$547d,$54cc,$551a,$5569
  910.         .dc.w        $55b8,$5607,$5656,$56a5,$56f4,$5744,$5793,$57e2
  911.         .dc.w        $5832,$5882,$58d1,$5921,$5971,$59c1,$5a10,$5a60
  912.         .dc.w        $5ab0,$5b01,$5b51,$5ba1,$5bf1,$5c42,$5c92,$5ce3
  913.         .dc.w        $5d34,$5d84,$5dd5,$5e26,$5e77,$5ec8,$5f19,$5f6a
  914.         .dc.w        $5fbb,$600d,$605e,$60b0,$6101,$6153,$61a4,$61f6
  915.         .dc.w        $6248,$629a,$62ec,$633e,$6390,$63e2,$6434,$6487
  916.         .dc.w        $64d9,$652c,$657e,$65d1,$6624,$6676,$66c9,$671c
  917.         .dc.w        $676f,$67c2,$6815,$6869,$68bc,$690f,$6963,$69b6
  918.         .dc.w        $6a0a,$6a5e,$6ab1,$6b05,$6b59,$6bad,$6c01,$6c55
  919.         .dc.w        $6caa,$6cfe,$6d52,$6da7,$6dfb,$6e50,$6ea4,$6ef9
  920.         .dc.w        $6f4e,$6fa3,$6ff8,$704d,$70a2,$70f7,$714d,$71a2
  921.         .dc.w        $71f7,$724d,$72a2,$72f8,$734e,$73a4,$73fa,$7450
  922.         .dc.w        $74a6,$74fc,$7552,$75a8,$75ff,$7655,$76ac,$7702
  923.         .dc.w        $7759,$77b0,$7807,$785e,$78b4,$790c,$7963,$79ba
  924.         .dc.w        $7a11,$7a69,$7ac0,$7b18,$7b6f,$7bc7,$7c1f,$7c77
  925.         .dc.w        $7ccf,$7d27,$7d7f,$7dd7,$7e2f,$7e88,$7ee0,$7f38
  926.         .dc.w        $7f91,$7fea,$8042,$809b,$80f4,$814d,$81a6,$81ff
  927.         .dc.w        $8259,$82b2,$830b,$8365,$83be,$8418,$8472,$84cb
  928.         .dc.w        $8525,$857f,$85d9,$8633,$868e,$86e8,$8742,$879d
  929.         .dc.w        $87f7,$8852,$88ac,$8907,$8962,$89bd,$8a18,$8a73
  930.         .dc.w        $8ace,$8b2a,$8b85,$8be0,$8c3c,$8c97,$8cf3,$8d4f
  931.         .dc.w        $8dab,$8e07,$8e63,$8ebf,$8f1b,$8f77,$8fd4,$9030
  932.         .dc.w        $908c,$90e9,$9146,$91a2,$91ff,$925c,$92b9,$9316
  933.         .dc.w        $9373,$93d1,$942e,$948c,$94e9,$9547,$95a4,$9602
  934.         .dc.w        $9660,$96be,$971c,$977a,$97d8,$9836,$9895,$98f3
  935.         .dc.w        $9952,$99b0,$9a0f,$9a6e,$9acd,$9b2c,$9b8b,$9bea
  936.         .dc.w        $9c49,$9ca8,$9d08,$9d67,$9dc7,$9e26,$9e86,$9ee6
  937.         .dc.w        $9f46,$9fa6,$a006,$a066,$a0c6,$a127,$a187,$a1e8
  938.         .dc.w        $a248,$a2a9,$a30a,$a36b,$a3cc,$a42d,$a48e,$a4ef
  939.         .dc.w        $a550,$a5b2,$a613,$a675,$a6d6,$a738,$a79a,$a7fc
  940.         .dc.w        $a85e,$a8c0,$a922,$a984,$a9e7,$aa49,$aaac,$ab0e
  941.         .dc.w        $ab71,$abd4,$ac37,$ac9a,$acfd,$ad60,$adc3,$ae27
  942.         .dc.w        $ae8a,$aeed,$af51,$afb5,$b019,$b07c,$b0e0,$b145
  943.         .dc.w        $b1a9,$b20d,$b271,$b2d6,$b33a,$b39f,$b403,$b468
  944.         .dc.w        $b4cd,$b532,$b597,$b5fc,$b662,$b6c7,$b72c,$b792
  945.         .dc.w        $b7f7,$b85d,$b8c3,$b929,$b98f,$b9f5,$ba5b,$bac1
  946.         .dc.w        $bb28,$bb8e,$bbf5,$bc5b,$bcc2,$bd29,$bd90,$bdf7
  947.         .dc.w        $be5e,$bec5,$bf2c,$bf94,$bffb,$c063,$c0ca,$c132
  948.         .dc.w        $c19a,$c202,$c26a,$c2d2,$c33a,$c3a2,$c40b,$c473
  949.         .dc.w        $c4dc,$c544,$c5ad,$c616,$c67f,$c6e8,$c751,$c7bb
  950.         .dc.w        $c824,$c88d,$c8f7,$c960,$c9ca,$ca34,$ca9e,$cb08
  951.         .dc.w        $cb72,$cbdc,$cc47,$ccb1,$cd1b,$cd86,$cdf1,$ce5b
  952.         .dc.w        $cec6,$cf31,$cf9c,$d008,$d073,$d0de,$d14a,$d1b5
  953.         .dc.w        $d221,$d28d,$d2f8,$d364,$d3d0,$d43d,$d4a9,$d515
  954.         .dc.w        $d582,$d5ee,$d65b,$d6c7,$d734,$d7a1,$d80e,$d87b
  955.         .dc.w        $d8e9,$d956,$d9c3,$da31,$da9e,$db0c,$db7a,$dbe8
  956.         .dc.w        $dc56,$dcc4,$dd32,$dda0,$de0f,$de7d,$deec,$df5b
  957.         .dc.w        $dfc9,$e038,$e0a7,$e116,$e186,$e1f5,$e264,$e2d4
  958.         .dc.w        $e343,$e3b3,$e423,$e493,$e503,$e573,$e5e3,$e654
  959.         .dc.w        $e6c4,$e735,$e7a5,$e816,$e887,$e8f8,$e969,$e9da
  960.         .dc.w        $ea4b,$eabc,$eb2e,$eb9f,$ec11,$ec83,$ecf5,$ed66
  961.         .dc.w        $edd9,$ee4b,$eebd,$ef2f,$efa2,$f014,$f087,$f0fa
  962.         .dc.w        $f16d,$f1e0,$f253,$f2c6,$f339,$f3ad,$f420,$f494
  963.         .dc.w        $f507,$f57b,$f5ef,$f663,$f6d7,$f74c,$f7c0,$f834
  964.         .dc.w        $f8a9,$f91e,$f992,$fa07,$fa7c,$faf1,$fb66,$fbdc
  965.         .dc.w        $fc51,$fcc7,$fd3c,$fdb2,$fe28,$fe9e,$ff14,$ff8a
  966.  
  967.                             * ADPCM BASE FRQ        15.6/31.2 kHz
  968. func_04xx_01_08:lsr.l        #3,d1            * 音程1/8倍        無し/3.9 kHz
  969.         movea.l        CH_TPCNST_CADR(a5),a0
  970.         jmp        (a0)
  971. func_04xx_01_06:moveq.l        #6,d0            * 音程1/6倍        無し/5.2 kHz
  972.         div32_16
  973.         movea.l        CH_TPCNST_CADR(a5),a0
  974.         jmp        (a0)
  975. func_04xx_01_04:lsr.l        #2,d1            * 音程1/4倍        3.9/7.8 kHz
  976.         movea.l        CH_TPCNST_CADR(a5),a0
  977.         jmp        (a0)
  978. func_04xx_01_03:moveq.l        #3,d0            * 音程1/3倍        5.2/10.4 kHz
  979.         div32_16
  980.         movea.l        CH_TPCNST_CADR(a5),a0
  981.         jmp        (a0)
  982. func_04xx_01_02:lsr.l        #1,d1            * 音程1/2倍        7.8/15.6 kHz
  983.         movea.l        CH_TPCNST_CADR(a5),a0
  984.         jmp        (a0)
  985. func_04xx_02_03:add.l        d1,d1            * 音程2/3倍        10.4/20.8 kHz
  986.         moveq.l        #3,d0
  987.         div32_16
  988.         movea.l        CH_TPCNST_CADR(a5),a0
  989.         jmp        (a0)
  990. func_04xx_01_01:movea.l        CH_TPCNST_CADR(a5),a0    * 音程1/1倍(そのまんま)    15.6/31.2 kHz
  991.         jmp        (a0)
  992. func_04xx_04_03:add.l        d1,d1            * 音程4/3倍        20.8/無し kHz
  993.         add.l        d1,d1
  994.         moveq.l        #3,d0
  995.         div32_16
  996.         movea.l        CH_TPCNST_CADR(a5),a0
  997.         jmp        (a0)
  998. func_04xx_02_01:add.l        d1,d1
  999.         movea.l        CH_TPCNST_CADR(a5),a0    * 音程2/1倍        31.2/無し kHz
  1000.         jmp        (a0)
  1001. func_04xx_08_03:lsl.l        #3,d1            * 音程8/3倍
  1002.         moveq.l        #3,d0
  1003.         div32_16
  1004.         movea.l        CH_TPCNST_CADR(a5),a0
  1005.         jmp        (a0)
  1006. func_04xx_04_01:add.l        d1,d1
  1007.         add.l        d1,d1
  1008.         movea.l        CH_TPCNST_CADR(a5),a0    * 音程4/1倍
  1009.         jmp        (a0)
  1010.  
  1011. CALC_TPCNSTADP:    moveq.l        #0,d0            * 戻り値クリア
  1012.         move.w        CH_VOL_OFFS(a5),d4
  1013.  
  1014.         cmpi.l        #$0001_0000,d1
  1015.         bhi        1f
  1016.         beq        2f
  1017.         cmpi.w        #$AAAA,d1
  1018.         beq        3f
  1019.         cmpi.w        #$8000,d1
  1020.         beq        4f
  1021.         cmpi.w        #$5555,d1
  1022.         beq        5f
  1023.         cmpi.w        #$4000,d1
  1024.         beq        6f
  1025.         move.l        d1,d2            * 1回の割り込みで進むアドレス計算
  1026.         lsl.l        #4,d2            * ADPCM
  1027.         move.l        d2,d3
  1028.         add.l        d2,d2
  1029.         add.l        d3,d2            * d2.l = CH_PITCH*48
  1030.         clr.w        d2
  1031.         swap.w        d2
  1032.         addq.l        #1,d2            * d2.l = TPCNST
  1033.  
  1034.         lea.l        AtoP_low_tbl(pc),a0
  1035.         move.l        a0,CH_CNVADR_BASE(a5)
  1036.         move.w        sr,d3
  1037.         ori.w        #$0700,sr
  1038.         move.l        #AtoP_low,CH_JMP_ADR(a5)
  1039.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 低音変換
  1040.         move.l        d1,CH_PITCH(a5)
  1041.         move.l        d2,CH_TPCNST(a5)
  1042.         move.w        d3,sr
  1043.         rts
  1044.  
  1045. 1:        move.l        d1,d2            * 1回の割り込みで進むアドレス計算
  1046.         lsl.l        #4,d2            * ADPCM
  1047.         move.l        d2,d3
  1048.         add.l        d2,d2
  1049.         add.l        d3,d2            * d2.l = CH_PITCH*48
  1050.         clr.w        d2
  1051.         swap.w        d2
  1052.         addq.l        #1,d2            * d2.l = TPCNST
  1053.  
  1054.         lea.l        AtoP_high_tbl(pc),a0
  1055.         move.l        a0,CH_CNVADR_BASE(a5)
  1056.         move.w        sr,d3
  1057.         ori.w        #$0700,sr
  1058.         move.l        #AtoP_high,CH_JMP_ADR(a5)
  1059.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 高音変換
  1060.         move.l        d1,CH_PITCH(a5)
  1061.         move.l        d2,CH_TPCNST(a5)
  1062.         move.w        d3,sr
  1063.         rts
  1064. 2:        lea.l        AtoP_0101_tbl(pc),a0
  1065.         move.l        a0,CH_CNVADR_BASE(a5)
  1066.         move.w        sr,d3
  1067.         ori.w        #$0700,sr
  1068.         move.l        #AtoP_0101,CH_JMP_ADR(a5)
  1069.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 15.6kHz
  1070.         move.w        d3,sr
  1071.         rts
  1072. 3:        lea.l        AtoP_0203_tbl(pc),a0
  1073.         move.l        a0,CH_CNVADR_BASE(a5)
  1074.         move.w        sr,d3
  1075.         ori.w        #$0700,sr
  1076.         move.l        #AtoP_0203,CH_JMP_ADR(a5)
  1077.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 10.4kHz
  1078.         move.w        d3,sr
  1079.         rts
  1080. 4:        lea.l        AtoP_0102_tbl(pc),a0
  1081.         move.l        a0,CH_CNVADR_BASE(a5)
  1082.         move.w        sr,d3
  1083.         ori.w        #$0700,sr
  1084.         move.l        #AtoP_0102,CH_JMP_ADR(a5)
  1085.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 7.8kHz
  1086.         move.w        d3,sr
  1087.         rts
  1088. 5:        lea.l        AtoP_0103_tbl(pc),a0
  1089.         move.l        a0,CH_CNVADR_BASE(a5)
  1090.         move.w        sr,d3
  1091.         ori.w        #$0700,sr
  1092.         move.l        #AtoP_0103,CH_JMP_ADR(a5)
  1093.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 5.2kHz
  1094.         move.w        d3,sr
  1095.         rts
  1096. 6:        lea.l        AtoP_0104_tbl(pc),a0
  1097.         move.l        a0,CH_CNVADR_BASE(a5)
  1098.         move.w        sr,d3
  1099.         ori.w        #$0700,sr
  1100.         move.l        #AtoP_0104,CH_JMP_ADR(a5)
  1101.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * AtoP 3.8kHz
  1102.         move.w        d3,sr
  1103.         rts
  1104.  
  1105. CALC_TPCNST16:    moveq.l        #0,d0            * 戻り値クリア
  1106.         move.w        CH_VOL_OFFS(a5),d4
  1107.  
  1108.         cmpi.l        #$0001_0000,d1
  1109.         bhi        1f
  1110.         beq        2f
  1111.         cmpi.w        #$AAAA,d1
  1112.         beq        3f
  1113.         cmpi.w        #$8000,d1
  1114.         beq        4f
  1115.         cmpi.w        #$5555,d1
  1116.         beq        5f
  1117.         cmpi.w        #$4000,d1
  1118.         beq        6f
  1119.  
  1120.         move.l        d1,d2
  1121.         lsl.l        #5,d2            * 16bit PCM
  1122.         move.l        d2,d3
  1123.         add.l        d2,d2
  1124.         add.l        d3,d2            * d2.l = CH_PITCH*96
  1125.         clr.w        d2
  1126.         swap.w        d2
  1127.         addq.l        #1,d2
  1128.         add.l        d2,d2            * ここがポイント
  1129.  
  1130.         lea.l        PCM16_low_tbl(pc),a0
  1131.         move.l        a0,CH_CNVADR_BASE(a5)
  1132.         move.w        sr,d3
  1133.         ori.w        #$0700,sr
  1134.         move.l        #PCM16_low,CH_JMP_ADR(a5)
  1135.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 低音変換
  1136.         move.l        d1,CH_PITCH(a5)
  1137.         move.l        d2,CH_TPCNST(a5)
  1138.         move.w        d3,sr
  1139.         rts
  1140.  
  1141. 1:        move.l        d1,d2
  1142.         lsl.l        #5,d2            * 16bit PCM
  1143.         move.l        d2,d3
  1144.         add.l        d2,d2
  1145.         add.l        d3,d2            * d2.l = CH_PITCH*96
  1146.         clr.w        d2
  1147.         swap.w        d2
  1148.         addq.l        #1,d2
  1149.         add.l        d2,d2            * ここがポイント
  1150.  
  1151.         lea.l        PCM16_high_tbl(pc),a0
  1152.         move.l        a0,CH_CNVADR_BASE(a5)
  1153.         move.w        sr,d3
  1154.         ori.w        #$0700,sr
  1155.         move.l        #PCM16_high,CH_JMP_ADR(a5)
  1156.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 高音変換
  1157.         move.l        d1,CH_PITCH(a5)
  1158.         move.l        d2,CH_TPCNST(a5)
  1159.         move.w        d3,sr
  1160.         rts
  1161. 2:        lea.l        PCM16_0101_tbl(pc),a0
  1162.         move.l        a0,CH_CNVADR_BASE(a5)
  1163.         move.w        sr,d3
  1164.         ori.w        #$0700,sr
  1165.         move.l        #PCM16_0101,CH_JMP_ADR(a5)
  1166.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 15.6kHz
  1167.         move.w        d3,sr
  1168.         rts
  1169. 3:        lea.l        PCM16_0203_tbl(pc),a0
  1170.         move.l        a0,CH_CNVADR_BASE(a5)
  1171.         move.w        sr,d3
  1172.         ori.w        #$0700,sr
  1173.         move.l        #PCM16_0203,CH_JMP_ADR(a5)
  1174.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 10.4kHz
  1175.         move.w        d3,sr
  1176.         rts
  1177. 4:        lea.l        PCM16_0102_tbl(pc),a0
  1178.         move.l        a0,CH_CNVADR_BASE(a5)
  1179.         move.w        sr,d3
  1180.         ori.w        #$0700,sr
  1181.         move.l        #PCM16_0102,CH_JMP_ADR(a5)
  1182.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 7.8kHz
  1183.         move.w        d3,sr
  1184.         rts
  1185. 5:        lea.l        PCM16_0103_tbl(pc),a0
  1186.         move.l        a0,CH_CNVADR_BASE(a5)
  1187.         move.w        sr,d3
  1188.         ori.w        #$0700,sr
  1189.         move.l        #PCM16_0103,CH_JMP_ADR(a5)
  1190.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 5.2kHz
  1191.         move.w        d3,sr
  1192.         rts
  1193. 6:        lea.l        PCM16_0104_tbl(pc),a0
  1194.         move.l        a0,CH_CNVADR_BASE(a5)
  1195.         move.w        sr,d3
  1196.         ori.w        #$0700,sr
  1197.         move.l        #PCM16_0104,CH_JMP_ADR(a5)
  1198.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM16 3.8kHz
  1199.         move.w        d3,sr
  1200.         rts
  1201.  
  1202. CALC_TPCNST8:    moveq.l        #0,d0            * 戻り値クリア
  1203.         move.w        CH_VOL_OFFS(a5),d4
  1204.  
  1205.         cmpi.l        #$0001_0000,d1
  1206.         bhi        1f
  1207.         beq        2f
  1208.         cmpi.w        #$AAAA,d1
  1209.         beq        3f
  1210.         cmpi.w        #$8000,d1
  1211.         beq        4f
  1212.         cmpi.w        #$5555,d1
  1213.         beq        5f
  1214.         cmpi.w        #$4000,d1
  1215.         beq        6f
  1216.  
  1217.         move.l        d1,d2
  1218.         lsl.l        #5,d2            * 8bit PCM
  1219.         move.l        d2,d3
  1220.         add.l        d2,d2
  1221.         add.l        d3,d2            * d2.l = CH_PITCH*96
  1222.         clr.w        d2
  1223.         swap.w        d2
  1224.         addq.l        #1,d2
  1225.  
  1226.         lea.l        PCM8_low_tbl(pc),a0
  1227.         move.l        a0,CH_CNVADR_BASE(a5)
  1228.         move.w        sr,d3
  1229.         ori.w        #$0700,sr
  1230.         move.l        #PCM8_low,CH_JMP_ADR(a5)
  1231.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 低音変換
  1232.         move.l        d1,CH_PITCH(a5)
  1233.         move.l        d2,CH_TPCNST(a5)
  1234.         move.w        d3,sr
  1235.         rts
  1236.  
  1237. 1:        move.l        d1,d2
  1238.         lsl.l        #5,d2            * 8bit PCM
  1239.         move.l        d2,d3
  1240.         add.l        d2,d2
  1241.         add.l        d3,d2            * d2.l = CH_PITCH*96
  1242.         clr.w        d2
  1243.         swap.w        d2
  1244.         addq.l        #1,d2
  1245.  
  1246.         lea.l        PCM8_high_tbl(pc),a0
  1247.         move.l        a0,CH_CNVADR_BASE(a5)
  1248.         move.w        sr,d3
  1249.         ori.w        #$0700,sr
  1250.         move.l        #PCM8_high,CH_JMP_ADR(a5)
  1251.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 高音変換
  1252.         move.l        d1,CH_PITCH(a5)
  1253.         move.l        d2,CH_TPCNST(a5)
  1254.         move.w        d3,sr
  1255.         rts
  1256. 2:        lea.l        PCM8_0101_tbl(pc),a0
  1257.         move.l        a0,CH_CNVADR_BASE(a5)
  1258.         move.w        sr,d3
  1259.         ori.w        #$0700,sr
  1260.         move.l        #PCM8_0101,CH_JMP_ADR(a5)
  1261.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 15.6kHz
  1262.         move.w        d3,sr
  1263.         rts
  1264. 3:        lea.l        PCM8_0203_tbl(pc),a0
  1265.         move.l        a0,CH_CNVADR_BASE(a5)
  1266.         move.w        sr,d3
  1267.         ori.w        #$0700,sr
  1268.         move.l        #PCM8_0203,CH_JMP_ADR(a5)
  1269.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 10.4kHz
  1270.         move.w        d3,sr
  1271.         rts
  1272. 4:        lea.l        PCM8_0102_tbl(pc),a0
  1273.         move.l        a0,CH_CNVADR_BASE(a5)
  1274.         move.w        sr,d3
  1275.         ori.w        #$0700,sr
  1276.         move.l        #PCM8_0102,CH_JMP_ADR(a5)
  1277.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 7.8kHz
  1278.         move.w        d3,sr
  1279.         rts
  1280. 5:        lea.l        PCM8_0103_tbl(pc),a0
  1281.         move.l        a0,CH_CNVADR_BASE(a5)
  1282.         move.w        sr,d3
  1283.         ori.w        #$0700,sr
  1284.         move.l        #PCM8_0103,CH_JMP_ADR(a5)
  1285.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 5.2kHz
  1286.         move.w        d3,sr
  1287.         rts
  1288. 6:        lea.l        PCM8_0104_tbl(pc),a0
  1289.         move.l        a0,CH_CNVADR_BASE(a5)
  1290.         move.w        sr,d3
  1291.         ori.w        #$0700,sr
  1292.         move.l        #PCM8_0104,CH_JMP_ADR(a5)
  1293.         move.l        (a0,d4.w),CH_JMP_ADR2(a5)    * PCM8 3.8kHz
  1294.         move.w        d3,sr
  1295.         rts
  1296.  
  1297. CALC_TPCNSTNO:    move.l        #NO_PCM,CH_JMP_ADR(a5)    * データ無しの場合
  1298.         rts
  1299.  
  1300. *===============================================================
  1301. * func_05xx    : PCM 音量設定
  1302. * call        : d1.b = 音量
  1303. *             64 が原音量
  1304. *          a5.l = チャンネルワークアドレス
  1305. * return    : 特に無し
  1306. *===============================================================
  1307.  
  1308.  
  1309. func_05xx:    movea.l        CH_CNVADR_BASE(a5),a0
  1310.         andi.w        #$007f,d1            * NO_PCMの場合は機能しないので気にしない
  1311.         move.w        d1,CH_USER_VOL(a5)
  1312.         add.w        d1,d1
  1313.         move.w        func_05xx_tbl(pc,d1.w),d0    * 音量を実際値に変換
  1314.         move.w        d0,CH_VOL(a5)            * ワークに保存
  1315.         beq        func_05xx_Vx0            * 0だったら専用ルーチンへ
  1316.  
  1317.         lea.l        func_05xx_scantbl(pc),a1
  1318.         moveq.l        #-4,d1
  1319.         moveq.l        #16-1,d2
  1320. @@:        addq.w        #4,d1
  1321.         cmp.w        (a1)+,d0            * 高速化できる音量か調べる
  1322.         beq        @f
  1323.         dbra        d2,@b
  1324.  
  1325.         move.w        #16*4,CH_VOL_OFFS(a5)        * 掛け算を使う音量である
  1326.         move.l        16*4(a0),CH_JMP_ADR2(a5)
  1327.         moveq.l        #0,d0
  1328.         rts
  1329.  
  1330. func_05xx_Vx0:    move.w        #17*4,CH_VOL_OFFS(a5)        * 音量0である
  1331.         move.l        17*4(a0),CH_JMP_ADR2(a5)
  1332.         moveq.l        #0,d0
  1333.         rts
  1334.  
  1335. @@:        move.w        d1,CH_VOL_OFFS(a5)
  1336.         move.l        (a0,d1.w),CH_JMP_ADR2(a5)    * 音量計算の専用ルーチンへ
  1337.         moveq.l        #0,d0
  1338.         rts
  1339.  
  1340. func_05xx_tbl:    .dc.w          16,  17,  18,  19,  20,  21,  22,  23    * 実際に掛ける値(n/128)
  1341.         .dc.w          24,  25,  26,  27,  28,  29,  30,  31
  1342.         .dc.w          32,  33,  34,  35,  36,  37,  38,  39
  1343.         .dc.w          40,  41,  42,  43,  44,  45,  46,  47
  1344.         .dc.w          48,  50,  52,  54,  56,  58,  60,  62
  1345.         .dc.w          64,  66,  68,  70,  72,  74,  76,  78
  1346.         .dc.w          80,  82,  84,  86,  88,  90,  92,  94
  1347.         .dc.w          96, 100, 104, 108, 112, 116, 120, 124
  1348.         .dc.w         128, 132, 136, 140, 144, 148, 152, 156
  1349.         .dc.w         160, 164, 168, 172, 176, 180, 184, 188
  1350.         .dc.w         192, 200, 208, 216, 224, 232, 240, 248
  1351.         .dc.w         256, 264, 272, 280, 288, 296, 304, 312
  1352.         .dc.w         320, 328, 336, 344, 352, 360, 368, 376
  1353.         .dc.w         384, 400, 416, 432, 448, 464, 480, 496
  1354.         .dc.w         512, 528, 544, 560, 576, 592, 608, 624
  1355.         .dc.w         640, 656, 672, 688, 704, 720, 736, 752
  1356.  
  1357. func_05xx_scantbl:
  1358.         .dc.w          16,  24,  32,  40,  48,  64,  80,  96
  1359.         .dc.w         128, 160, 192, 256, 320, 384, 512, 640
  1360.  
  1361.  
  1362. *===============================================================
  1363. * func_06xx    : PCM PAN 設定
  1364. * call        : d1.b =   0:無音 1:左 2:右 3:中央    (3段階指定)
  1365. *             $80 + 0(左)~64(中央)~127(右) (128段階指定)
  1366. *          a5.l = チャンネルワークアドレス
  1367. * return    : 特に無し
  1368. *===============================================================
  1369.  
  1370. func_06xx:    move.b        d1,CH_PAN+1(a5)            * PAN保存
  1371.         bmi        1f
  1372.         andi.w        #$0003,d1
  1373.         move.b        pan_tbl3-mpw(a6,d1.w),ADPCM_pan-mpw(a6)
  1374.         st.b        pan_set_flag-mpw(a6)
  1375.         moveq.l        #0,d0
  1376.         rts
  1377. 1:        andi.w        #$007f,d1
  1378.         lsr.w        #5,d1
  1379.         move.b        pan_tbl128-mpw(a6,d1.w),ADPCM_pan-mpw(a6)
  1380.         st.b        pan_set_flag-mpw(a6)
  1381.         moveq.l        #0,d0
  1382.         rts
  1383.  
  1384. *===============================================================
  1385. * func_07xx    : PCM 種類変更
  1386. * call        : d1.b = PCM 種類 
  1387. *             ($ff = ADPCM / $00 = 無し / $01 = 16bitPCM / $02 = 8bitPCM)
  1388. *          a5.l = チャンネルワークアドレス
  1389. * return    : 特に無し
  1390. *===============================================================
  1391.  
  1392. func_07xx:    cmp.b        CH_PCM_KIND(a5),d1
  1393.         beq        func_07xx_end
  1394.  
  1395.         move.b        d1,CH_PCM_KIND(a5)
  1396.         bmi        f07xx_ADPCM
  1397.         beq        f07xx_NOPCM
  1398.         sub.b        #$02,d1
  1399.         bmi        f07xx_PCM16
  1400.  
  1401. f07xx_PCM8:    move.l        #CALC_TPCNST8,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  1402.         move.w        CH_USER_NOTE(a5),d1
  1403.         bra        func_04xx_x        * 音程再設定
  1404.  
  1405. f07xx_PCM16:    btst.b        #0,CH_LPEND_ADR+3(a5)
  1406.         beq        1f
  1407.         add.l        #1,CH_LPEND_ADR(a5)            * LP終端を偶数に合わせる
  1408. 1:        move.l        #CALC_TPCNST16,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  1409.         move.w        CH_USER_NOTE(a5),d1
  1410.         bra        func_04xx_x        * 音程再設定
  1411.  
  1412. f07xx_ADPCM:    move.l        #CALC_TPCNSTADP,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  1413.         move.w        CH_USER_NOTE(a5),d1
  1414.         bra        func_04xx_x        * 音程再設定
  1415.  
  1416. f07xx_NOPCM:    move.l        #CALC_TPCNSTNO,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  1417.         move.l        #NO_PCM,CH_JMP_ADR(a5)    * データ無しの場合
  1418.  
  1419. func_07xx_end:    rts
  1420.  
  1421. *===============================================================
  1422. * func_10xx    : PCM 効果音再生
  1423. * call        : d1.l = PCM種類(-1:ADPCM 0:データ無し 1:16bitPCM 2:8bitPCM) * $01000000
  1424. *            +音量(現在は64のみ指定可) * $010000
  1425. *            +再生周波数(0:3.9kHz 1:5.2kHz 2:7.8kHz 3:10.4kHz 4:15.6kHz 5:20.4kHz 6:31.2kHz) * $0100
  1426. *            +PAN(0-3 / $80+0-126 / $ff)
  1427. *          d2.l = PCM長さ(バイト数)
  1428. *          a1.l = PCMアドレス
  1429. *          a5.l = チャンネルワークアドレス
  1430. * return    : 特に無し
  1431. *===============================================================
  1432.  
  1433. func_10xx:
  1434.         clr.b        EFCT_PLAY_FLAG(a5)    * PLAY_FLAG OFF
  1435.  
  1436.         move.l        a1,EFCT_PCM_ADR(a5)    * アドレス保存
  1437.         move.l        d2,EFCT_PCM_LEN(a5)    * 長さ保存
  1438.         beq        func_13xx        * 長さ0 = keyoff
  1439.  
  1440. * PAN
  1441.         move.b        d1,EFCT_PAN+1(a5)    * PAN 保存
  1442.         move.b        d1,d0
  1443.         bmi        1f
  1444.         andi.w        #$0003,d0        * PAN 3段階指定
  1445.         move.b        pan_tbl3-mpw(a6,d0.w),ADPCM_pan-mpw(a6)
  1446.         bra        2f
  1447. 1:        andi.w        #$007f,d0        * PAN 128段階指定
  1448.         lsr.w        #5,d0
  1449.         move.b        pan_tbl128-mpw(a6,d0.w),ADPCM_pan-mpw(a6)
  1450. 2:        st.b        pan_set_flag-mpw(a6)
  1451.  
  1452.         * FRQ
  1453.         move.w        d1,d0
  1454.         lsr.w        #8,d0
  1455.         cmpi.b        #$06+1,d0
  1456.         bcc        func_10xx_err
  1457.         move.b        d0,EFCT_FRQ+1(a5)    * FRQ保存
  1458.         add.w        d0,d0
  1459.         add.w        d0,d0
  1460.         add.w        frq_offset-mpw(a6),d0    * 高周波数対応
  1461.  
  1462. @@:        swap.w        d1
  1463.         lsr.w        #8,d1
  1464.         tst.b        d1
  1465.         bmi        1f            * ADPCM
  1466.         bhi        2f            * 16/8 bit PCM
  1467.         bra        func_10xx_err        * 終わり
  1468. 1:        move.b        d1,EFCT_PCM_KIND(a5)
  1469.         move.l        AtoP_EFCT_tbl-mpw(a6,d0.w),EFCT_JMP_ADR(a5)
  1470.         move.l        #AtoP_tbl,EFCT_AtoP_X(a5)
  1471.         clr.w        EFCT_AtoP_Y(a5)
  1472.         bra        4f
  1473. 2:        move.b        d1,EFCT_PCM_KIND(a5)
  1474.         subq.b        #1,d1
  1475.         bne        3f
  1476.         move.l        PCM16_EFCT_tbl-mpw(a6,d0.w),EFCT_JMP_ADR(a5)
  1477.         bra        4f
  1478. 3:        move.l        PCM8_EFCT_tbl-mpw(a6,d0.w),EFCT_JMP_ADR(a5)
  1479.  
  1480. 4:        clr.b        EFCT_PLAY_MODE(a5)    * 通常再生
  1481.         st.b        EFCT_PLAY_FLAG(a5)    * PLAY_FLAG ON
  1482.  
  1483.         bra        func_00xx_DMA_start
  1484.  
  1485. func_10xx_err:    move.l        #NO_PCM,EFCT_JMP_ADR(a5)    * PCM種類 = none
  1486.         moveq.l        #-1,d0            * 異状終了コード
  1487.         rts
  1488.  
  1489. *===============================================================
  1490. * func_13xx    : PCM 効果停止
  1491. * call        : 無し
  1492. * return    : 無し
  1493. *===============================================================
  1494.  
  1495. func_13xx:    clr.b        EFCT_PLAY_FLAG(a5)
  1496.         moveq.l        #0,d0
  1497.         rts
  1498.  
  1499.  
  1500. *===============================================================
  1501. * func_8000    : MPCM占有
  1502. * call        : a1.l = 占有するアプリケーション名の文字列アドレス
  1503. * return    : d0.l = 0    占有できた
  1504. *               < 0    占有できなかった
  1505. *===============================================================
  1506. func_8000:    tst.b        (a1)
  1507.         beq        func_8000_err        * (a1.l)=null error!
  1508.         moveq.l        #0,d0
  1509.         move.b        mpcm_locked-mpw(a6),d0
  1510.         addq.b        #1,d0
  1511.         cmpi.b        #32+1,d0
  1512.         bcc        func_8000_err
  1513.         move.b        d0,mpcm_locked-mpw(a6)
  1514.  
  1515.         lea.l        mplock_app_name-mpw(a6),a0    * a0.l = app name buffer address
  1516.         moveq.l        #32-1,d0
  1517. 1:        tst.b        (a0)
  1518.         beq        @f
  1519.         lea.l        32(a0),a0
  1520.         dbra        d0,1b
  1521. @@:
  1522.         moveq.l        #32-1,d0
  1523. 1:        move.b        (a1)+,(a0)+
  1524.         dbeq        d0,1b
  1525.  
  1526.         tst.w        d0
  1527.         bpl        1f
  1528.         clr.b        -(a0)            * null terminate
  1529. 1:        moveq.l        #0,d0
  1530.         rts
  1531.  
  1532. func_8000_err:    moveq.l        #-1,d0
  1533.         rts
  1534.  
  1535. *===============================================================
  1536. * func_8001    : MPCM占有解除
  1537. * call        : a1.l = 占有解除するアプリケーション名の文字列アドレス
  1538. * return    : d0.l = 0    占有解除できた
  1539. *               < 0    占有されていなかった
  1540. *===============================================================
  1541. func_8001:    move.b        mpcm_locked-mpw(a6),d0
  1542.         subq.b        #1,d0
  1543.         bcs        func_8001_err
  1544.  
  1545.         lea.l        mplock_app_name-mpw(a6),a0
  1546.         moveq.l        #32-1,d0
  1547. 1:        tst.b        (a0)
  1548.         beq        3f
  1549.         movea.l        a1,a2
  1550.         movea.l        a0,a3
  1551.         moveq.l        #32-1,d1
  1552. 2:        move.b        (a2)+,d2
  1553.         move.b        (a3)+,d3
  1554.         or.b        d2,d3
  1555.         beq        @f            * 0.b 同志なら比較終了
  1556.         cmp.b        d2,d3
  1557.         dbne        d1,2b            * 32文字いくか違うのにあたるまで
  1558. 3:        lea.l        32(a0),a0
  1559.         dbra        d0,1b
  1560.         bra        func_8001_err        * 無いぞ!
  1561.  
  1562. @@:        clr.b        (a0)            * バッファ先頭をnull clear
  1563.         moveq.l        #1,d0
  1564.         sub.b        d0,mpcm_locked-mpw(a6)
  1565.         moveq.l        #0,d0
  1566.         rts
  1567. func_8001_err:    moveq.l        #-1,d0
  1568.         rts
  1569.  
  1570. *===============================================================
  1571. * func_8002    : MPCM初期化
  1572. * call        : 無し
  1573. * return    : 無し
  1574. *===============================================================
  1575.  
  1576. func_8002:    move.w        sr,d6
  1577.         ori.w        #$0700,sr        * 割り込み禁止
  1578.  
  1579.         bsr        init_channel_work    * 全チャンネルワーク初期化
  1580.  
  1581.         clr.b        ADPCM_SYSWORK.w        * IOCS 初期化
  1582.  
  1583.         move.w        frq_offset-mpw(a6),d0
  1584.         beq        2f
  1585.         cmpi.w        #4*2,d0
  1586.         beq        1f
  1587.         move.w        #$0203,d1        * ADPCM 7.8kHz
  1588.         bra        @f
  1589. 1:        move.w        #$0403,d1        * ADPCM 15.6kHz
  1590.         bra        @f
  1591. 2:        move.w        #$0603,d1        * ADPCM 31.2kHz
  1592. @@:        bsr        ADPCM_mode        * 周波数15.6kHz/PAN左右
  1593.         move.b        #$02,ADPCM+1        * ADPCM再生動作開始
  1594.  
  1595.         lea.l        DMA3,a0            * DMA 初期化
  1596.         move.b        #$04,SCR(a0)        * SCR clear
  1597.         move.b        #$10,DCCR(a0)        * CCR DMA停止割り込み無し
  1598.         move.b        #$80,DCR(a0)        * DCR clear
  1599.         move.b        #$02,OCR(a0)        * OCR clear
  1600.         move.b        #$01,CPR(a0)
  1601.         move.b        #$05,MFC(a0)
  1602.         move.b        #$05,DFC(a0)
  1603.  
  1604.         move.l        #dummy_ADPCM,MAR(a0)    * $88を通常出力
  1605.         move.l        #ADPCM+3,DAR(a0)    * ADPCM データレジスタ
  1606.         move.w        #8,MTC(a0)        * 8バイトだけ
  1607.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  1608.         move.b        #$80,DCCR(a0)        * DMA START/割り込み無し
  1609.  
  1610.         move.w        d6,sr
  1611.         moveq.l        #0,d0
  1612.         rts
  1613.  
  1614.  
  1615. init_channel_work:
  1616.  
  1617. *         演奏ワーク初期化
  1618.  
  1619.         lea.l        ch0_work(pc),a5
  1620.         moveq.l        #CH_MAX-1,d0            * d0.l = loop counter
  1621.         moveq.l        #1,d1                * d1.l = channel mask bit
  1622.  
  1623. @@:        clr.b        CH_KEY_STAT(a5)            * KEY STATUS    : non
  1624.         clr.b        CH_PLAY_FLAG(a5)        * CH PLAY    : non
  1625.  
  1626.         clr.b        CH_PCM_KIND(a5)                * PCM KIND    : NO DATA
  1627.         move.l        #NO_PCM,CH_JMP_ADR(a5)            * 飛び先
  1628.         move.l        #CALC_TPCNSTNO,CH_TPCNST_CADR(a5)    * アドレス増分計算アドレス
  1629.         move.l        #AtoP_0101_tbl,CH_CNVADR_BASE(a5)    * 変換ルーチンアドレステーブルのベースアドレス
  1630.  
  1631.  
  1632.         move.l        #func_04xx_01_01,CH_PITCH_CADR(a5)    * 音程変換関係
  1633.         move.l        #$0001_0000,CH_ORG_PITCH(a5)
  1634.         move.l        #$0001_0000,CH_PITCH(a5)
  1635.         clr.w        CH_PITCH_CTR(a5)
  1636.         clr.w        CH_ORG_NOTE(a5)
  1637.         clr.w        CH_USER_NOTE(a5)
  1638.         move.b        #$80,CH_USER_FRQ(a5)            * 周波数はなにもない
  1639.  
  1640.         move.l        #CALC_TPCNSTADP,CH_TPCNST_CADR(a5)    * トラップ関係
  1641.         move.l        #$0000_0001*48,CH_TPCNST(a5)
  1642.         move.l        #AtoP_END,CH_TRAP_ROUTINE(a5)        * トラップ時の処理アドレス
  1643.  
  1644.         move.l        #$0000_0001,CH_LPTIME(a5)        * ループ無し
  1645.         move.l        #$0000_0001,CH_LPTIME_CTR(a5)
  1646.  
  1647.         move.w        #64,CH_VOL(a5)                * 音量
  1648.         move.w        #8*4,CH_VOL_OFFS(a5)            * 専用ルーチンオフセット
  1649.         move.w        #64,CH_PAN(a5)                * PAN
  1650.  
  1651.         move.l        #AtoP_tbl,CH_AtoP_X(a5)        * ADPCM->PCM変換X
  1652.         clr.w        CH_AtoP_Y(a5)            * ADPCM->PCM変換Y
  1653.         clr.w        CH_LAST_PCM(a5)            * LAST PCM
  1654.         st.b        CH_ODDEVEN(a5)            * 処理してたADPCMの偶・奇
  1655.         move.w        #$0040,CH_PAN(a5)        * PAN (128段階)
  1656.         move.l        d1,CH_CHANNEL_MASK(a5)        * チャンネルマスクビットパターン
  1657.  
  1658.         add.l        d1,d1                * マスクをシフト
  1659.         lea.l        CH_WORK_SIZE(a5),a5
  1660.         dbra        d0,@b
  1661.  
  1662. *        効果音&IOCSワーク初期化
  1663.  
  1664.         moveq.l        #EFCT_MAX+1-1,d0        * d0.l = ループカウンタ
  1665.         move.l        #$0080_0000,d1            * d3.l = チャンネルマスク
  1666. @@:        move.l        #NO_PCM,EFCT_JMP_ADR(a5)    * データ無し
  1667.         clr.l        EFCT_PCM_ADR(a5)        * PCMアドレス
  1668.         clr.l        EFCT_PCM_LEN(a5)        * PCM長さ
  1669.         clr.l        EFCT_CTBL_ADR(a5)        * チェーンテーブルアドレス
  1670.         clr.w        EFCT_CTBL_N(a5)            * チェーンテーブルの数
  1671.         move.l        #AtoP_tbl,EFCT_AtoP_X(a5)    * ADPCM->PCM変換X
  1672.         clr.w        EFCT_AtoP_Y(a5)            * ADPCM->PCM変換Y
  1673.         move.l        d1,EFCT_CH_MASK(a5)        * チャンネルマスク
  1674.         clr.b        EFCT_PLAY_FLAG(a5)        * PLAY FLAG クリア
  1675.         clr.b        EFCT_PLAY_MODE(a5)        * PLAY MODE 通常
  1676.  
  1677.         add.l        d1,d1                * マスクをシフト
  1678.         lea.l        EFCT_WORK_SIZE(a5),a5
  1679.         dbra        d0,@b
  1680.  
  1681. *        割り込みワーク初期化
  1682.  
  1683.         move.l        #PtoA_tbl,PtoA_X
  1684.         clr.w        PtoA_Y
  1685.         st.b        ADPCM_out_flag-mpw(a6)
  1686.         clr.b        ADPCM_pan-mpw(a6)
  1687.         clr.l        play_flag-mpw(a6)
  1688.         clr.b        pan_set_flag-mpw(a6)
  1689.         move.w        #-1,mpcm_nest            * 多重割り込み回数
  1690.         move.w        #-100,overload_ctr        * 過負荷時のリトライ回数
  1691.         move.w        #$0008,efct_poly-mpw(a6)    * 効果音8音まで発声
  1692.  
  1693. .ifdef    FCTRACE
  1694.         move.l        #TEXT_RAM+$40000,fc_logadr-mpw(a6)    * funcログ書き込みアドレス
  1695. .endif
  1696.  
  1697.         rts
  1698.  
  1699. *===============================================================
  1700. * func_8003    : DMA割り込み中のMPU/MFPのマスク設定
  1701. * call        : d1.l = マスクデータ
  1702. *          <0 割り込みマスク収得
  1703. *          ≧0 割り込みマスク設定
  1704. *
  1705. *          ビット18~16 : MPU 割り込みレベル(0~7 推奨3以上)
  1706. *            15~8  : MFP 割り込みマスクA (IMRA)
  1707. *             7~0  : MFP 割り込みマスクB (IMRB)
  1708. *          ビット15~0では、1で割り込み前と同じ状態になる。
  1709. *          よーするにMFPのIMRA,IMRBとANDをとっている。
  1710. *
  1711. * return    : d0.l = 変更前の割り込みマスク
  1712. *             関係ないビット(31~19)は0になる。
  1713. *===============================================================
  1714.  
  1715. func_8003:    move.w        MPU_mask-mpw(a6),d0
  1716.         lsr.w        #8,d0
  1717.         swap.w        d0
  1718.         move.b        IMR_mask+1-mpw(a6),d0
  1719.         lsl.w        #8,d0
  1720.         move.b        IMR_mask+3-mpw(a6),d0    * d0.l = 元のマスク
  1721.  
  1722.         tst.l        d1
  1723.         bmi        @f
  1724.  
  1725.         move.w        sr,d0
  1726.         ori.w        #$0700,sr        * 割り込み禁止
  1727.         move.b        d1,IMR_mask+3-mpw(a6)    * mask設定
  1728.         lsr.w        #8,d1
  1729.         move.b        d1,IMR_mask+1-mpw(a6)
  1730.         swap.w        d1
  1731.         lsl.w        #8,d1
  1732.         andi.w        #$0700,d1
  1733.         move.w        d1,MPU_mask-mpw(a6)
  1734.         move.w        d0,sr
  1735. @@:        rts
  1736.  
  1737. *===============================================================
  1738. * func_8004    : MPCM動作モード設定
  1739. * call        : d1.l = 設定データ
  1740. *          <0 モード収得
  1741. *          ≧0 モード設定
  1742. *
  1743. * return    : d0.l = 動作モード
  1744. *             関係ないビット(31~2)は0になる。
  1745. *===============================================================
  1746. func_8004:    tst.l        d1
  1747.         bmi        func_8004_get
  1748.  
  1749. *        move.l        d1,mpcm_mode-mpw(a6)
  1750.         rts
  1751.  
  1752. func_8004_get:    move.l        mpcm_mode-mpw(a6),d0
  1753.         rts
  1754.  
  1755.  
  1756. *===============================================================
  1757. * func_8005    : MPCM音量マップ設定
  1758. * call        : d1.l = 設定モード(0:128段階 / 1:16段階 / $ff:ユーザー設定)
  1759. *          a1.l = 音量テーブルアドレス(ユーザー設定時)
  1760. * return    : 無し
  1761. *===============================================================
  1762. func_8005:    tst.b        volume_mode-mpw(a6)
  1763.         bne        func_8005_end            * 音量固定モード
  1764.         tst.l        d1
  1765.         bmi        func_8005_user            * ユーザー定義へ
  1766.         beq        1f
  1767.         lea.l        func_8005_tbl1(pc),a1        * 16段階テーブル
  1768.         bra        func_8005_user
  1769. 1:        lea.l        func_8005_tbl2(pc),a1        * 128段階テーブル
  1770. func_8005_user:    lea.l        func_05xx_tbl(pc),a0
  1771.         moveq.l        #128/2-1,d0
  1772. @@:        move.l        (a1)+,(a0)+
  1773.         dbra        d0,@b
  1774. func_8005_end:    rts
  1775.  
  1776. func_8005_tbl1:    .dc.w          16,  16,  16,  16,  16,  16,  16,  16    * 音量16段階
  1777.         .dc.w          24,  24,  24,  24,  24,  24,  24,  24
  1778.         .dc.w          32,  32,  32,  32,  32,  32,  32,  32
  1779.         .dc.w          40,  40,  40,  40,  40,  40,  40,  40
  1780.         .dc.w          48,  48,  48,  48,  48,  48,  48,  48
  1781.         .dc.w          64,  64,  64,  64,  64,  64,  64,  64
  1782.         .dc.w          80,  80,  80,  80,  80,  80,  80,  80
  1783.         .dc.w          96,  96,  96,  96,  96,  96,  96,  96
  1784.         .dc.w         128, 128, 128, 128, 128, 128, 128, 128
  1785.         .dc.w         160, 160, 160, 160, 160, 160, 160, 160
  1786.         .dc.w         192, 192, 192, 192, 192, 192, 192, 192
  1787.         .dc.w         256, 256, 256, 256, 256, 256, 256, 256
  1788.         .dc.w         320, 320, 320, 320, 320, 320, 320, 320
  1789.         .dc.w         384, 384, 384, 384, 384, 384, 384, 384
  1790.         .dc.w         512, 512, 512, 512, 512, 512, 512, 512
  1791.         .dc.w         640, 640, 640, 640, 640, 640, 640, 640
  1792.  
  1793. func_8005_tbl2:    .dc.w          16,  17,  18,  19,  20,  21,  22,  23    * 音量128段階
  1794.         .dc.w          24,  25,  26,  27,  28,  29,  30,  31
  1795.         .dc.w          32,  33,  34,  35,  36,  37,  38,  39
  1796.         .dc.w          40,  41,  42,  43,  44,  45,  46,  47
  1797.         .dc.w          48,  50,  52,  54,  56,  58,  60,  62
  1798.         .dc.w          64,  66,  68,  70,  72,  74,  76,  78
  1799.         .dc.w          80,  82,  84,  86,  88,  90,  92,  94
  1800.         .dc.w          96, 100, 104, 108, 112, 116, 120, 124
  1801.         .dc.w         128, 132, 136, 140, 144, 148, 152, 156
  1802.         .dc.w         160, 164, 168, 172, 176, 180, 184, 188
  1803.         .dc.w         192, 200, 208, 216, 224, 232, 240, 248
  1804.         .dc.w         256, 264, 272, 280, 288, 296, 304, 312
  1805.         .dc.w         320, 328, 336, 344, 352, 360, 368, 376
  1806.         .dc.w         384, 400, 416, 432, 448, 464, 480, 496
  1807.         .dc.w         512, 528, 544, 560, 576, 592, 608, 624
  1808.         .dc.w         640, 656, 672, 688, 704, 720, 736, 752
  1809.  
  1810. *===============================================================
  1811. * func_8006    : 効果音発声数設定
  1812. * call        : d1.l = 効果音発声数(0-8)
  1813. *             0 の時は最大数指定とみなす
  1814. * return    : 無し
  1815. *===============================================================
  1816. func_8006:    cmpi.w        #EFCT_MAX+1,d1
  1817.         bcc        @f
  1818.         subq.w        #1,d1
  1819.         bpl        1f
  1820.         moveq.l        #EFCT_MAX,d1                * 0なら最大
  1821. 1:        move.w        d1,efct_poly-mpw(a6)
  1822. @@:        rts
  1823.  
  1824.  
  1825.  
  1826.  
  1827. *===============================================================
  1828. * func_8010    : MPCMのチャンネルワークアドレス問い合わせ
  1829. * call        : 無し
  1830. * return    : d0.l = 先頭アドレス
  1831. *          ワークのサイズは1チャンネルにつき128バイト。
  1832. *          チャンネル0から15まで順に並んでいる。
  1833. *===============================================================
  1834. func_8010:    move.l        #ch0_work,d0
  1835.         rts
  1836.  
  1837. *===============================================================
  1838. * func_8011    : MPCMのシステムワークアドレス問い合わせ
  1839. * call        : 無し
  1840. * return    : d0.l = 先頭アドレス
  1841. *          下手にいじると暴走するので注意して使ってください。
  1842. *===============================================================
  1843. func_8011:    move.l        #mpw,d0
  1844.         rts
  1845.  
  1846. *===============================================================
  1847. * func_8012    : MPCMのチャンネル指定ファンクションの
  1848. *         処理ルーチンアドレス問い合わせ
  1849. * call        : 無し
  1850. * return    : d0.l = アドレステーブルの先頭アドレス
  1851. *          func_00xxから番号順に並んでいる
  1852. *===============================================================
  1853. func_8012:    move.l        #trap1_jmp_tbl0,d0
  1854.         rts
  1855.  
  1856. *===============================================================
  1857. * func_8013    : MPCMの全体ファンクションの処理ルーチンアドレス
  1858. *         問い合わせ
  1859. * call        : 無し
  1860. * return    : d0.l = アドレステーブルの先頭アドレス
  1861. *          func_8000から番号順に並んでいる
  1862. *===============================================================
  1863. func_8013:    move.l        #trap1_jmp_tbl1,d0
  1864.         rts
  1865.  
  1866.  
  1867. *▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
  1868. *
  1869. *        IOCSコール処理
  1870. *
  1871. *△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△
  1872.  
  1873. *===============================================================
  1874. * IOCS    _ADPCMOUT
  1875. * call        : d0.l = IOCSコール番号
  1876. *          d1.w = サンプリング周波数 * 256 + PAN
  1877. *          d2.l = データ長さ
  1878. *          a1.l = データアドレス
  1879. *===============================================================
  1880.  
  1881. mpcm_iocs_60:    movem.l        d1/d2/a0/a5/a6,-(sp)
  1882.  
  1883.         move.w        sr,d0
  1884.         ori.w        #$0700,sr        * 割り込み禁止
  1885.         btst.b        #2,ADPCM_SYSWORK.w    * 録音中?
  1886.         beq        @f
  1887.         move.w        d0,sr            * 録音中ならこのコールを無視
  1888.         movem.l        (sp)+,d1/d2/a0/a5/a6
  1889.         rts
  1890.  
  1891. @@:        move.b        #02,ADPCM_SYSWORK.w    * IOCS $60 実行中
  1892.  
  1893.         lea.l        IOCS_work(pc),a5
  1894.         lea.l        mpw(pc),a6
  1895.         clr.b        EFCT_PLAY_FLAG(a5)    * 演奏中止
  1896.  
  1897.         move.w        d0,sr
  1898.  
  1899.         move.l        a1,EFCT_PCM_ADR(a5)    * アドレス保存
  1900.         move.l        d2,EFCT_PCM_LEN(a5)    * 長さ保存
  1901.  
  1902.         move.w        d1,d2
  1903.         andi.w        #$0003,d2
  1904.         move.b        pan_tbl3-mpw(a6,d2.w),ADPCM_pan-mpw(a6)    * PAN変換/保存
  1905.         st.b        pan_set_flag-mpw(a6)    * PAN設定
  1906.  
  1907.         clr.b        d1
  1908.         lsr.w        #6,d1
  1909.         add.w        frq_offset-mpw(a6),d1
  1910.         move.l        AtoP_EFCT_tbl-mpw(a6,d1.w),EFCT_JMP_ADR(a5)
  1911.  
  1912.         move.l        #AtoP_tbl,EFCT_AtoP_X(a5)
  1913.         clr.w        EFCT_AtoP_Y(a5)
  1914.  
  1915.         clr.b        EFCT_PLAY_MODE(a5)    * 通常再生
  1916.         st.b        EFCT_PLAY_FLAG(a5)    * PLAY_FLAG ON
  1917.  
  1918.         tst.l        play_flag-mpw(a6)    * 今演奏中?
  1919.         bne        @f
  1920.         bsr        func_00xx_DMA_start        * DMA再起動
  1921. @@:        movem.l        (sp)+,d1/d2/a0/a5/a6
  1922.         rts
  1923.  
  1924. *===============================================================
  1925. * IOCS    _ADPCMINP
  1926. * call        : d0.l = IOCSコール番号
  1927. *          d1.w = サンプリング周波数 * 256 + PAN
  1928. *          d2.l = データ長さ
  1929. *          a1.l = データアドレス
  1930. *===============================================================
  1931.  
  1932.  
  1933. mpcm_iocs_61:    movem.l        d2/a0/a6,-(sp)        * IOCS _ADPCMINP
  1934.  
  1935.         lea.l        mpw(pc),a6
  1936.  
  1937.         move.w        sr,d0
  1938.         ori.w        #$0700,sr        * 割り込み禁止
  1939.  
  1940.         tst.b        ADPCM_SYSWORK.w        * 他のIOCSコール実行中?
  1941.         bne        @f
  1942.         tst.l        play_flag-mpw(a6)    * MPCM演奏中?
  1943.         bne        @f
  1944.  
  1945.         move.b        #$04,ADPCM_SYSWORK.w    * $61 実行中
  1946.  
  1947.         bsr        ADPCM_mode        * ADPCMの周波数/PAN設定(d1.wで)
  1948.  
  1949.         lea.l        DMA3,a0            * DMA初期化(録音用)
  1950.         move.w        #$8082,DCR(a0)        * I/O -> メモリ転送
  1951.         move.b        #$04,SCR(a0)
  1952.         move.b        #$01,CPR(a0)
  1953.         move.b        #$05,MFC(a0)
  1954.         move.b        #$05,DFC(a0)
  1955.         move.l        a1,MAR(a0)        * 録音メモリのアドレス
  1956.         move.l        #ADPCM+3,DAR(a0)    * ADPCM データレジスタ
  1957.  
  1958.         cmpi.l        #$0000_ff00,d2
  1959.         bhi        1f            * d2.l > ff00なら
  1960.         st.b        IOCS_REC_LEN-mpw(a6)    * 残り長さをマイナスにしておく
  1961.         move.w        d2,MTC(a0)        * 転送長をDMAに設定
  1962.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  1963.         move.b        #$88,DCCR(a0)        * 通常動作/割り込み有り
  1964.         move.b        #$04,ADPCM+1        * ADPCM recording start
  1965.         bra        @f
  1966.  
  1967. 1:        sub.l        #$0000_ff00,d2
  1968.         move.w        #$ff00,MTC(a0)        * 転送長をDMAに設定
  1969.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  1970.         move.b        #$88,DCCR(a0)        * 通常動作/割り込み有り
  1971.         move.b        #$04,ADPCM+1        * ADPCM recording start
  1972.  
  1973.         adda.l        #$0000_ff00,a1        * 次のアドレス
  1974.         move.l        a1,BAR(a0)
  1975.  
  1976.         cmpi.l        #$0000_ff00,d2
  1977.         bhi        1f            * d2.l > $ff00なら
  1978.         clr.l        IOCS_REC_LEN-mpw(a6)
  1979.         move.w        d2,BTC(a0)        * 残り長さ
  1980.         move.b        #$05,BFC(a0)
  1981.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  1982.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  1983.         bra        @f
  1984.  
  1985. 1:        sub.l        #$0000_ff00,d2
  1986.         move.l        d2,IOCS_REC_LEN-mpw(a6)    * 残り長さ保存
  1987.         move.w        #$ff00,BTC(a0)
  1988.         move.b        #$05,BFC(a0)
  1989.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  1990.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  1991.  
  1992. @@:        move.w        d0,sr            * sr 戻す
  1993.         movem.l        (sp)+,d2/a0/a6
  1994.         rts
  1995.  
  1996. *===============================================================
  1997. * IOCS    _ADPCMAOT
  1998. * call        : d0.l = IOCSコール番号
  1999. *          d1.w = サンプリング周波数 * 256 + PAN
  2000. *          d2.l = 出力データチェーンテーブル個数
  2001. *          a1.l = チェーンテーブルアドレス
  2002. *===============================================================
  2003.  
  2004. mpcm_iocs_62:    movem.l        d1/d2/a0/a1/a5/a6,-(sp)    * IOCS    _ADPCMAOT
  2005.  
  2006.         move.w        sr,d0
  2007.         ori.w        #$0700,sr        * 割り込み禁止
  2008.         btst.b        #2,ADPCM_SYSWORK.w    * 録音中?
  2009.         beq        @b
  2010.         move.w        d0,sr
  2011.         movem.l        (sp)+,d1/d2/a0/a1/a5/a6
  2012.         rts
  2013.  
  2014. @@:        move.b        #$12,ADPCM_SYSWORK.w    * IOCS $62 実行中
  2015.  
  2016.         lea.l        IOCS_work(pc),a5
  2017.         lea.l        mpw(pc),a6
  2018.         clr.b        EFCT_PLAY_FLAG(a5)    * 演奏中止
  2019.  
  2020.         move.w        d0,sr
  2021.  
  2022.         move.l        d2,EFCT_CTBL_N(a5)
  2023.         move.l        (a1)+,EFCT_PCM_ADR(a5)
  2024.         clr.w        EFCT_PCM_LEN(a5)
  2025.         move.w        (a1)+,EFCT_PCM_LEN+2(a5)
  2026.         move.l        a1,EFCT_CTBL_ADR(a5)
  2027.  
  2028.         move.w        d1,d2
  2029.         andi.w        #$0003,d2
  2030.         move.b        pan_tbl3-mpw(a6,d2.w),ADPCM_pan-mpw(a6)    * PAN変換/保存
  2031.         st.b        pan_set_flag-mpw(a6)
  2032.  
  2033.         clr.b        d1
  2034.         lsr.w        #6,d1
  2035.         add.w        frq_offset-mpw(a6),d1
  2036.         move.l        AtoP_EFCT_tbl-mpw(a6,d1.w),EFCT_JMP_ADR(a5)
  2037.  
  2038.         move.l        #AtoP_tbl,EFCT_AtoP_X(a5)
  2039.         clr.w        EFCT_AtoP_Y(a5)
  2040.  
  2041.         move.b        #$01,EFCT_PLAY_MODE(a5)    * アレイチェーン
  2042.         st.b        EFCT_PLAY_FLAG(a5)
  2043.  
  2044.         tst.l        play_flag-mpw(a6)
  2045.         bne        @f
  2046.         bsr        func_00xx_DMA_start
  2047. @@:        movem.l        (sp)+,d1/d2/a0/a1/a5/a6
  2048.         rts
  2049.  
  2050. *===============================================================
  2051. * IOCS    _ADPCMAIN
  2052. * call        : d0.l = IOCSコール番号
  2053. *          d1.w = サンプリング周波数 * 256 + PAN
  2054. *          d2.l = 出力データチェーンテーブル個数
  2055. *          a1.l = チェーンテーブルアドレス
  2056. *===============================================================
  2057.  
  2058. mpcm_iocs_63:    movem.l        d2/a0/a6,-(sp)        * IOCS _ADPCMAIN
  2059.  
  2060.         lea.l        mpw(pc),a6
  2061.  
  2062.         move.w        sr,d0
  2063.         ori.w        #$0700,sr        * 割り込み禁止
  2064.  
  2065.         tst.b        ADPCM_SYSWORK.w        * 他のIOCSコール実行中?
  2066.         bne        @f
  2067.         tst.l        play_flag-mpw(a6)    * MPCM演奏中?
  2068.         bne        @f
  2069.  
  2070.         move.b        #$14,ADPCM_SYSWORK.w    * $63 実行中
  2071.  
  2072.         move.w        d0,sr
  2073.  
  2074.         bsr        ADPCM_mode        * ADPCMの周波数/PAN設定(d1.wで)
  2075.  
  2076.         lea.l        DMA3,a0            * DMA初期化(録音用)
  2077.         move.w        #$8082,DCR(a0)        * I/O -> メモリ転送
  2078.         move.b        #$04,SCR(a0)
  2079.         move.b        #$01,CPR(a0)
  2080.         move.b        #$05,MFC(a0)
  2081.         move.b        #$05,DFC(a0)
  2082.         move.l        (a1)+,MAR(a0)        * 録音メモリのアドレス
  2083.         move.l        #ADPCM+3,DAR(a0)    * ADPCM データレジスタ
  2084.         move.w        (a1)+,d0
  2085.         andi.w        #$ff00,d0        * $ff00以上は転送しないよ
  2086.         move.w        d0,MTC(a0)        * 転送長をDMAに設定
  2087.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2088.         move.b        #$88,DCCR(a0)        * 通常動作/割り込み有り
  2089.         move.b        #$04,ADPCM+1        * ADPCM recording start
  2090.  
  2091.         sub.l        #1,d2            * テーブル1個しかない?
  2092.         beq        1f
  2093.  
  2094.         move.l        (a1)+,BAR(a0)        * 次のアドレス
  2095.         move.w        (a1)+,d0
  2096.         andi.w        #$ff00,d0        * $ff00以上は転送しないよ
  2097.         move.w        d0,BTC(a0)        * 残り長さ
  2098.         move.b        #$05,BFC(a0)
  2099.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2100.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  2101.  
  2102.         sub.l        #1,d2            * テーブル個数-1
  2103.  
  2104. 1:        move.l        a1,IOCS_REC_CTBL_ADR-mpw(a6)    * 次のテーブルアドレス
  2105.         move.l        d2,IOCS_REC_CTBL_N-mpw(a6)    * 残りテーブル
  2106.  
  2107.         bra        1f
  2108.  
  2109. @@:        move.w        d0,sr            * sr 戻す
  2110. 1:        movem.l        (sp)+,d2/a0/a6
  2111.         rts
  2112.  
  2113. *===============================================================
  2114. * IOCS    _ADPCMLOT
  2115. * call        : d0.l = IOCSコール番号
  2116. *          d1.w = サンプリング周波数 * 256 + PAN
  2117. *          a1.l = アレイチェーンテーブルアドレス
  2118. *===============================================================
  2119.  
  2120. mpcm_iocs_64:    movem.l        d1/d2/a0/a1/a5/a6,-(sp)    * _ADPCMLOT
  2121.  
  2122.         move.w        sr,d0
  2123.         ori.w        #$0700,sr        * 割り込み禁止
  2124.         btst.b        #2,ADPCM_SYSWORK.w    * 録音中?
  2125.         beq        @f
  2126.         move.w        d0,sr
  2127.         movem.l        (sp)+,d1/d2/a0/a1/a5/a6
  2128.         rts
  2129.  
  2130. @@:        move.b        #$14,ADPCM_SYSWORK.w    * IOCS $64 実行中
  2131.  
  2132.         lea.l        IOCS_work(pc),a5
  2133.         lea.l        mpw(pc),a6
  2134.         clr.b        EFCT_PLAY_FLAG(a5)    * 演奏中止
  2135.  
  2136.         move.w        d0,sr
  2137.  
  2138.         move.l        (a1)+,EFCT_PCM_ADR(a5)
  2139.         clr.w        EFCT_PCM_LEN(a5)
  2140.         move.w        (a1)+,EFCT_PCM_LEN+2(a5)
  2141.         move.l        (a1),EFCT_CTBL_ADR(a5)
  2142.  
  2143.         move.w        d1,d2
  2144.         andi.w        #$0003,d2
  2145.         move.b        pan_tbl3-mpw(a6,d2.w),ADPCM_pan-mpw(a6)    * PAN変換/保存
  2146.         st.b        pan_set_flag-mpw(a6)
  2147.  
  2148.         clr.b        d1
  2149.         lsr.w        #6,d1
  2150.         add.w        frq_offset-mpw(a6),d1
  2151.         move.l        AtoP_EFCT_tbl-mpw(a6,d1.w),EFCT_JMP_ADR(a5)
  2152.  
  2153.         move.l        #AtoP_tbl,EFCT_AtoP_X(a5)
  2154.         clr.w        EFCT_AtoP_Y(a5)
  2155.  
  2156.         move.b        #$02,EFCT_PLAY_MODE(a5)    * リンクアレイチェーン
  2157.         st.b        EFCT_PLAY_FLAG(a5)    * 再生開始
  2158.  
  2159.         tst.l        play_flag-mpw(a6)
  2160.         bne        @f
  2161.         bsr        func_00xx_DMA_start
  2162. @@:        movem.l        (sp)+,d1/d2/a0/a1/a5/a6
  2163.         rts
  2164.  
  2165. *===============================================================
  2166. * IOCS    _ADPCMLIN
  2167. * call        : d0.l = IOCSコール番号
  2168. *          d1.w = サンプリング周波数 * 256 + PAN
  2169. *          a1.l = アレイチェーンテーブルアドレス
  2170. *===============================================================
  2171.  
  2172. mpcm_iocs_65:    movem.l        d2/a0/a6,-(sp)        * IOCS _ADPCMAIN
  2173.  
  2174.         lea.l        mpw(pc),a6
  2175.  
  2176.         move.w        sr,d0
  2177.         ori.w        #$0700,sr        * 割り込み禁止
  2178.  
  2179.         tst.b        ADPCM_SYSWORK.w        * 他のIOCSコール実行中?
  2180.         bne        @f
  2181.         tst.l        play_flag-mpw(a6)    * MPCM演奏中?
  2182.         bne        @f
  2183.  
  2184.         move.b        #$24,ADPCM_SYSWORK.w    * $65 実行中
  2185.  
  2186.         move.w        d0,sr
  2187.  
  2188.         bsr        ADPCM_mode        * ADPCMの周波数/PAN設定(d1.wで)
  2189.  
  2190.         lea.l        DMA3,a0            * DMA初期化(録音用)
  2191.         move.w        #$8082,DCR(a0)        * I/O -> メモリ転送
  2192.         move.b        #$04,SCR(a0)
  2193.         move.b        #$01,CPR(a0)
  2194.         move.b        #$05,MFC(a0)
  2195.         move.b        #$05,DFC(a0)
  2196.         move.l        (a1)+,MAR(a0)        * 録音メモリのアドレス
  2197.         move.l        #ADPCM+3,DAR(a0)    * ADPCM データレジスタ
  2198.         move.w        (a1)+,d0
  2199.         andi.w        #$ff00,d0        * $ff00以上は転送しないよ
  2200.         move.w        d0,MTC(a0)        * 転送長をDMAに設定
  2201.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2202.         move.b        #$88,DCCR(a0)        * 通常動作/割り込み有り
  2203.         move.b        #$04,ADPCM+1        * ADPCM recording start
  2204.  
  2205.         movea.l        (a1)+,a1
  2206.         move.l        a1,d0            * テーブル1個しかない?
  2207.         beq        1f
  2208.  
  2209.         move.l        (a1)+,BAR(a0)        * 次のアドレス
  2210.         move.w        (a1)+,d0
  2211.         andi.w        #$ff00,d0        * $ff00以上は転送しないよ
  2212.         move.w        d0,BTC(a0)        * 残り長さ
  2213.         move.b        #$05,BFC(a0)
  2214.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2215.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  2216.  
  2217.         movea.l        (a1)+,a1
  2218.  
  2219. 1:        move.l        a1,IOCS_REC_CTBL_ADR-mpw(a6)    * 次のテーブルアドレス
  2220.         bra        1f
  2221.  
  2222. @@:        move.w        d0,sr            * sr 戻す
  2223. 1:        movem.l        (sp)+,d2/a0/a6
  2224.         rts
  2225.  
  2226. *===============================================================
  2227. * IOCS    _ADPCMSNS
  2228. *===============================================================
  2229.  
  2230. mpcm_iocs_66:    moveq.l        #0,d0            * _ADPCMSNS
  2231.         move.b        ADPCM_SYSWORK.w,d0
  2232.         rts
  2233.  
  2234. *===============================================================
  2235. * IOCS    _ADPCMMOD
  2236. * call        : d1.l = 制御番号
  2237. *===============================================================
  2238.  
  2239. mpcm_iocs_67:    movem.l        a0/a5-a6,-(sp)        * _ADPCMMOD
  2240.         lea.l        IOCS_work(pc),a5
  2241.         lea.l        mpw(pc),a6
  2242.  
  2243.         cmpi.b        #$02,d1
  2244.         bcc        @f
  2245.  
  2246.         clr.b        EFCT_PLAY_FLAG(a5)    * d1.l = $00/$01 終了/停止
  2247.         movem.l        (sp)+,a0/a5-a6
  2248.         rts
  2249.  
  2250. @@:        st.b        EFCT_PLAY_FLAG(a5)    * d1.l = $02 再開
  2251.  
  2252.         move.w        sr,d0
  2253.         ori.w        #$0700,sr        * 割り込み禁止
  2254.  
  2255.         tst.l        play_flag-mpw(a6)
  2256.         bne        @f
  2257.         bsr        func_00xx_DMA_start
  2258. @@:        move.w        d0,sr
  2259.         movem.l        (sp)+,a0/a5-a6
  2260.         rts
  2261.  
  2262. *===============================================================
  2263. * ADPCM_mode    : ADPCMのモードを切り替える
  2264. * call        : d1.w = サンプリング周波数*256+PAN
  2265. *          a6.l = ワークアドレス
  2266. * return    : 無し
  2267. * breaks    : 無し
  2268. *===============================================================
  2269.  
  2270. ADPCM_mode:    movem.l        d0-d2,-(sp)
  2271.  
  2272.         moveq.l        #$03,d2
  2273.         and.b        d1,d2
  2274.         move.b        pan_tbl3-mpw(a6,d2.w),d2    * d2.b = ADPCM PAN
  2275.         lsr.w        #8,d1
  2276.         moveq.l        #$f0,d0
  2277.         and.b        $E9A005,d0
  2278.         or.b        ADPCM_clk_tbl0(pc,d1.w),d0    * 周波数設定値を得る
  2279.         or.b        d2,d0            * PANと合成
  2280.         move.b        d0,$E9A005        * 8255 ポートC 設定(PAN=3)
  2281.  
  2282.         moveq.l        #$7f,d0            * OPM レジスタ $1Bの設定
  2283.         and.b        $09da.w,d0
  2284.         or.b        ADPCM_clk_tbl1(pc,d1.w),d0
  2285.         move.b        d0,$09da.w
  2286. @@:        tst.b        $E90003
  2287.         bmi.s        @b
  2288.         move.b        #$1b,$E90001
  2289.         nop
  2290.         nop
  2291.         nop
  2292.         nop                    * high clock 対応
  2293.         move.b        d0,$E90003
  2294.  
  2295.         movem.l        (sp)+,d0-d2
  2296.         rts
  2297. *                3.9  5.2  7.8 10.4 15.6 20.8 31.2 kHz
  2298. ADPCM_clk_tbl0:    .dc.b        $00, $04, $00, $04, $08, $0c, $0c    * to 8255
  2299. ADPCM_clk_tbl1:    .dc.b        $80, $80, $00, $00, $00, $80, $00    * to YM2151
  2300.  
  2301.  
  2302. *▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
  2303. *
  2304. *        DMA割り込み処理部分
  2305. *
  2306. *△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△
  2307.  
  2308. *===============================================================
  2309. *        IOCS録音用割り込みルーチン
  2310. *===============================================================
  2311.  
  2312. mpcm_rec:    move.b        ADPCM_SYSWORK.w,d0
  2313.         cmp.b        #$14,d0
  2314.         beq        mpcm_rec_63
  2315.         cmp.b        #$24,d0
  2316.         beq        mpcm_rec_65
  2317.  
  2318. * 通常の録音
  2319. mpcm_rec_61:    move.l        IOCS_REC_LEN-mpw(a6),d2
  2320.         bpl        @f
  2321.  
  2322. *        残り長さがマイナス
  2323.         move.b        #$01,ADPCM+1        * ADPCM 動作停止
  2324.  
  2325.         lea.l        DMA3,a0
  2326.         move.b        #$04,SCR(a0)        * SCR clear
  2327.         move.b        #$10,DCCR(a0)        * CCR DMA停止割り込み無し
  2328.         move.b        #$80,DCR(a0)        * DCR clear
  2329.         move.b        #$02,OCR(a0)        * OCR clear
  2330.         move.b        #$01,CPR(a0)
  2331.         move.b        #$05,MFC(a0)
  2332.         move.b        #$05,DFC(a0)
  2333.  
  2334.         move.w        frq_offset-mpw(a6),d0
  2335.         beq        2f
  2336.         cmpi.w        #4*2,d0
  2337.         beq        1f
  2338.         move.w        #$0203,d1        * ADPCM 7.8kHz
  2339.         bra        @f
  2340. 1:        move.w        #$0403,d1        * ADPCM 15.6kHz
  2341.         bra        @f
  2342. 2:        move.w        #$0603,d1        * ADPCM 31.2kHz
  2343. @@:        bsr        ADPCM_mode        * 周波数15.6kHz/PAN左右
  2344.         move.b        #$02,ADPCM+1        * ADPCM再生動作開始
  2345.         clr.b        ADPCM_SYSWORK.w        * IOCS 動作終了
  2346.         bra        mpcm_end
  2347.  
  2348. @@:        bne        @f
  2349.  
  2350. *        残り長さが0
  2351.         st.b        IOCS_REC_LEN-mpw(a6)    * 次は無いよ
  2352.         bra        mpcm_end        
  2353.  
  2354. *        残り長さが0以上
  2355. @@:        cmpi.l        #$0000_ff00,d2
  2356.         bhi        1f            * d2.l > ff00なら
  2357.         clr.l        IOCS_REC_LEN-mpw(a6)    * 残り長さを0にしておく
  2358.         bra        2f
  2359. 1:        sub.l        #$0000_ff00,d2
  2360.         move.l        d2,IOCS_REC_LEN-mpw(a6)    * 残りの長さを保存しておく
  2361.         move.w        #$ff00,d2
  2362. 2:        move.w        d2,MTC(a0)        * 転送長をDMAに設定
  2363.  
  2364.         move.b        #$05,BFC(a0)
  2365.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2366.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  2367.  
  2368.         bra        mpcm_end
  2369.  
  2370. *アレイ録音
  2371. mpcm_rec_63:    move.l        IOCS_REC_CTBL_N-mpw(a6),d2
  2372.         beq        @f
  2373.  
  2374.         move.l        (a1)+,BAR(a0)        * 次のアドレス
  2375.         move.w        (a1)+,d0
  2376.         andi.w        #$ff00,d0        * $ff00以上は転送しないよ
  2377.         move.w        d0,BTC(a0)        * 残り長さ
  2378.         move.b        #$05,BFC(a0)
  2379.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2380.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  2381.  
  2382.         subq.l        #1,d2
  2383.         move.l        d2,IOCS_REC_CTBL_N-mpw(a6)
  2384.         bra        mpcm_end
  2385.  
  2386. @@:        move.b        #$01,ADPCM+1        * ADPCM 動作停止
  2387.  
  2388.         lea.l        DMA3,a0
  2389.         move.b        #$04,SCR(a0)        * SCR clear
  2390.         move.b        #$10,DCCR(a0)        * CCR DMA停止割り込み無し
  2391.         move.b        #$80,DCR(a0)        * DCR clear
  2392.         move.b        #$02,OCR(a0)        * OCR clear
  2393.         move.b        #$01,CPR(a0)
  2394.         move.b        #$05,MFC(a0)
  2395.         move.b        #$05,DFC(a0)
  2396.  
  2397.         move.w        frq_offset-mpw(a6),d0
  2398.         beq        2f
  2399.         cmpi.w        #4*2,d0
  2400.         beq        1f
  2401.         move.w        #$0203,d1        * ADPCM 7.8kHz
  2402.         bra        @f
  2403. 1:        move.w        #$0403,d1        * ADPCM 15.6kHz
  2404.         bra        @f
  2405. 2:        move.w        #$0603,d1        * ADPCM 31.2kHz
  2406. @@:        bsr        ADPCM_mode        * 周波数15.6kHz/PAN左右
  2407.  
  2408.         move.b        #$02,ADPCM+1        * ADPCM再生動作開始
  2409.         clr.b        ADPCM_SYSWORK.w        * IOCS 動作終了
  2410.         bra        mpcm_end
  2411.  
  2412. * リンクアレイ録音
  2413. mpcm_rec_65:    movea.l        IOCS_REC_CTBL_ADR-mpw(a6),a1
  2414.         move.l        a1,d0
  2415.         beq        @f
  2416.  
  2417.         move.l        (a1)+,BAR(a0)        * 次のアドレス
  2418.         move.w        (a1)+,d0
  2419.         andi.w        #$ff00,d0        * $ff00以上は転送しないよ
  2420.         move.w        d0,BTC(a0)        * 残り長さ
  2421.         move.b        #$05,BFC(a0)
  2422.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2423.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  2424.  
  2425.         movea.l        (a1)+,a1
  2426.         move.l        a1,IOCS_REC_CTBL_ADR-mpw(a6)
  2427.         bra        mpcm_end
  2428.  
  2429. @@:        move.b        #$01,ADPCM+1        * ADPCM 動作停止
  2430.  
  2431.         lea.l        DMA3,a0
  2432.         move.b        #$04,SCR(a0)        * SCR clear
  2433.         move.b        #$10,DCCR(a0)        * CCR DMA停止割り込み無し
  2434.         move.b        #$80,DCR(a0)        * DCR clear
  2435.         move.b        #$02,OCR(a0)        * OCR clear
  2436.         move.b        #$01,CPR(a0)
  2437.         move.b        #$05,MFC(a0)
  2438.         move.b        #$05,DFC(a0)
  2439.  
  2440.         move.w        frq_offset-mpw(a6),d0
  2441.         beq        2f
  2442.         cmpi.w        #4*2,d0
  2443.         beq        1f
  2444.         move.w        #$0203,d1        * ADPCM 7.8kHz
  2445.         bra        @f
  2446. 1:        move.w        #$0403,d1        * ADPCM 15.6kHz
  2447.         bra        @f
  2448. 2:        move.w        #$0603,d1        * ADPCM 31.2kHz
  2449. @@:        bsr        ADPCM_mode        * 周波数15.6kHz/PAN左右
  2450.  
  2451.         move.b        #$02,ADPCM+1        * ADPCM再生動作開始
  2452.         clr.b        ADPCM_SYSWORK.w        * IOCS 動作終了
  2453.         bra        mpcm_end
  2454.  
  2455. *===============================================================
  2456. *        DMAエラー割り込み処理
  2457. *===============================================================
  2458.  
  2459. mpcm_err:
  2460.         move.b        DMA3+CER,DMA_err_stat
  2461. *        rte
  2462.  
  2463. *===============================================================
  2464. *        DMA転送終了割り込み処理
  2465. *===============================================================
  2466.  
  2467. mpcm:        ori.w        #$0700,sr        * 割り込み禁止
  2468.         addq.w        #1,mpcm_nest
  2469.         beq        @f
  2470.  
  2471. *        多重割り込み対応部分
  2472.         move.b        DMA3+CSR,DMA3+CSR    * CSR リセット
  2473.         bmi        1f            * 転送が終了していたら
  2474.         rte
  2475. 1:
  2476.         btst.b        #2,ADPCM_SYSWORK.w    * 録音の時か?
  2477.         bne        2f
  2478.         move.b        #$88,ADPCM+3        * 終了
  2479.         rte
  2480. 2:        move.b        #$01,ADPCM+1        * 録音動作停止
  2481.         clr.b        ADPCM_SYSWORK.w
  2482.         rte
  2483.  
  2484. @@:        tst.b        mpcm_debug
  2485.         beq        @f
  2486.         move.w        #%00000_00000_01111_0,TEXT_PALET
  2487.  
  2488. @@:        movem.l        d0-d7/a0-a6,-(sp)
  2489.  
  2490.         lea.l        mpw(pc),a6        * MPCM 割り込みワークの先頭
  2491.  
  2492.         ori.w        #$0700,sr        * 割り込み禁止
  2493.         move.l        MFP+$12,d0
  2494.         move.l        d0,-(sp)        * IMRA/IMRB 保存
  2495.         and.l        IMR_mask-mpw(a6),d0
  2496.         move.l        d0,MFP+$12        * IMRA/IMRB 書き替え
  2497.  
  2498.         move.w        sr,d0            * mpu maskの変更
  2499.         andi.w        #$f8ff,d0
  2500.         or.w        MPU_mask-mpw(a6),d0
  2501.         move.w        d0,sr
  2502.  
  2503.         btst.b        #2,ADPCM_SYSWORK.w    * 録音?
  2504.         bne        mpcm_rec        * (オフセットの関係で)上にあります
  2505.  
  2506.  
  2507. *        PANの設定
  2508.         tst.b        pan_set_flag-mpw(a6)
  2509.         beq        @f
  2510.         clr.b        pan_set_flag-mpw(a6)    * フラグクリア
  2511.         moveq.l        #$fc,d0
  2512.         and.b        $E9A005,d0        * 8255 PORT C
  2513.         or.b        ADPCM_pan-mpw(a6),d0
  2514.         move.b        d0,$E9A005        * ADPCM PAN 変更
  2515.  
  2516.  
  2517. *        16bit PCM 合成バッファ初期化
  2518. mpcm_loop:
  2519. @@:        lea.l        PCM_out+MIX_SIZE*4-mpw(a6),a1
  2520.         moveq.l        #0,d0
  2521.         moveq.l        #0,d1
  2522.         moveq.l        #0,d2
  2523.         moveq.l        #0,d3
  2524.         moveq.l        #0,d4
  2525.         moveq.l        #0,d5
  2526.         moveq.l        #0,d6
  2527.         moveq.l        #0,d7
  2528.         movem.l        d0-d7,-(a1)
  2529.         movem.l        d0-d7,-(a1)
  2530.         movem.l        d0-d7,-(a1)
  2531.         movem.l        d0-d7,-(a1)
  2532.         movem.l        d0-d7,-(a1)
  2533.         movem.l        d0-d7,-(a1)
  2534.  
  2535.  
  2536.  
  2537. *        演奏チャンネルPCM合成
  2538.         clr.l        play_flag-mpw(a6)    * play_flag クリア
  2539.         lea.l        ch0_work(pc),a5        * チャンネルワーク
  2540.  
  2541.         REPT        CH_MAX
  2542.         tst.b        CH_PLAY_FLAG(a5)
  2543.         beq        @f
  2544.         lea.l        PCM_out-mpw(a6),a1    * PCM 作成バッファ
  2545.         move.l        a6,-(sp)        * a6.l保存
  2546.         movea.l        CH_JMP_ADR(a5),a0
  2547.         jsr        (a0)
  2548.         movea.l        (sp)+,a6
  2549.         move.l        CH_CHANNEL_MASK(a5),d0
  2550.         or.l        d0,play_flag-mpw(a6)
  2551. @@:        lea.l        CH_WORK_SIZE(a5),a5
  2552.         ENDM
  2553.  
  2554. *        効果音チャンネルPCM合成
  2555.         REPT        EFCT_MAX
  2556.         tst.b        EFCT_PLAY_FLAG(a5)
  2557.         beq        @f
  2558.         lea.l        PCM_out-mpw(a6),a1    * PCM 作成バッファ
  2559.         movea.l        EFCT_JMP_ADR(a5),a0
  2560.         jsr        (a0)
  2561.         move.l        EFCT_CH_MASK(a5),d0
  2562.         or.l        d0,play_flag-mpw(a6)
  2563. @@:        lea.l        EFCT_WORK_SIZE(a5),a5
  2564.         ENDM
  2565.  
  2566. *        IOCSチャンネルPCM合成
  2567.         tst.b        EFCT_PLAY_FLAG(a5)    * IOCS再生中?
  2568.         beq        @f
  2569.         lea.l        PCM_out-mpw(a6),a1    * PCM 作成バッファ
  2570.         movea.l        EFCT_JMP_ADR(a5),a0
  2571.         jsr        (a0)
  2572.         move.l        EFCT_CH_MASK(a5),d0
  2573.         or.l        d0,play_flag-mpw(a6)
  2574.  
  2575. @@:        tst.l        play_flag-mpw(a6)    * 演奏終了か?
  2576.         bne        @f
  2577.  
  2578. mpcm_overload:    lea.l        DMA3,a0            * 演奏終了処理
  2579.         ori.w        #$0700,sr
  2580.         btst.b        #3,CSR(a0)        * CSR ACTビット(過負荷時のチェック)
  2581.         bne        1f
  2582.  
  2583.         move.w        #8,MTC(a0)        * DMAが止まっている時
  2584.         move.b        #$05,MFC(a0)
  2585.         move.l        #dummy_ADPCM,MAR(a0)    * $88を通常出力
  2586.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2587.         move.b        #$80,DCCR(a0)        * DMA START/割り込み無し
  2588.         bra        mpcm_end
  2589.  
  2590. 1:
  2591.         move.w        #8,BTC(a0)
  2592.         move.b        #$05,BFC(a0)
  2593.         move.l        #dummy_ADPCM,BAR(a0)    * $88を継続で出力
  2594.         move.b        CSR(a0),CSR(a0)
  2595.         move.b        #$40,DCCR(a0)        * 継続動作/転送終了割込無し
  2596.         bra        mpcm_end
  2597.  
  2598. @@:
  2599.  
  2600. *--------------    PCM -> ADPCM 変換 ----------------
  2601.  
  2602.         tst.b        mpcm_debug-mpw(a6)
  2603.         beq        @f
  2604.         move.w        #%00000_00000_11111_0,TEXT_PALET
  2605.  
  2606. @@:        neg.w        ADPCM_out_flag-mpw(a6)
  2607.         bmi        1f
  2608.         lea.l        ADPCM_out0-mpw(a6),a0
  2609.         bra        @f
  2610. 1:        lea.l        ADPCM_out1-mpw(a6),a0    * a0.l = 今回作成するADPCMバッファ
  2611.  
  2612. @@:        lea.l        PCM_out-mpw(a6),a1    * a1.l = 16bit PCM 合成バッファ
  2613.         movea.l        PtoA_X-mpw(a6),a2    * a2.l = PCM -> ADPCM テーブルアドレス
  2614.         move.w        PtoA_Y-mpw(a6),d1    * d1.w = PCM -> ADPCM 予測値
  2615.         moveq.l        #0,d2            * d2.w = 上位8bit CLR
  2616.         moveq.l        #$08,d5
  2617.         movea.w        d5,a3            * a3.w = $0008
  2618.         moveq.l        #$0f,d5            * d5.w = $000f
  2619.         moveq.l        #$80,d6
  2620.         movea.w        d6,a4            * a4.w = $0080
  2621.         moveq.l        #$f0,d6            * d6.w = $00f0
  2622.  
  2623.  
  2624.         REPT        MIX_SIZE        * MIX_SIZE*2個の16PCMを処理
  2625.  
  2626.         move.w        (a1)+,d0
  2627.         sub.w        d1,d0
  2628.         bmi        2f
  2629.         cmp.w        (a2)+,d0
  2630.         bcc        1f
  2631.         move.b        48(a2,d0.w),d2
  2632.         add.w        d2,a2
  2633. 1:        move.w        (a2)+,d3
  2634.         and.w        d5,d3            * andi.w #$000f,d3
  2635.         add.w        (a2)+,d1
  2636.         bra.s        3f
  2637.  
  2638. 2:        neg.w        d0
  2639.         cmp.w        (a2)+,d0
  2640.         bcc        1f
  2641.         move.b        48(a2,d0.w),d2
  2642.         add.w        d2,a2
  2643. 1:        move.w        (a2)+,d3
  2644.         and.w        d5,d3            * andi.w #$000f,d3
  2645.         add.w        a3,d3            * ori.w  #$0008,d3
  2646.         sub.w        (a2)+,d1
  2647.  
  2648. 3:        adda.w        (a2),a2
  2649.  
  2650.  
  2651.         move.w        (a1)+,d0
  2652.         sub.w        d1,d0
  2653.         bmi        2f
  2654.         cmp.w        (a2)+,d0
  2655.         bcc        1f
  2656.         move.b        48(a2,d0.w),d2
  2657.         add.w        d2,a2
  2658. 1:        move.w        (a2)+,d4
  2659.         and.w        d6,d4            * andi.w #$00f0,d4
  2660.         or.w        d4,d3
  2661.         add.w        (a2)+,d1
  2662.         bra.s        3f
  2663.  
  2664. 2:        neg.w        d0
  2665.         cmp.w        (a2)+,d0
  2666.         bcc        1f
  2667.         move.b        48(a2,d0.w),d2
  2668.         add.w        d2,a2
  2669. 1:        move.w        (a2)+,d4
  2670.         and.w        d6,d4            * andi.w #$00f0,d4
  2671.         add.w        a4,d4            * ori.w  #$0080,d4
  2672.         or.w        d4,d3
  2673.         sub.w        (a2)+,d1
  2674.  
  2675. 3:        adda.w        (a2),a2
  2676.         move.b        d3,(a0)+
  2677.  
  2678.         ENDM
  2679.  
  2680.         move.l        a2,PtoA_X-mpw(a6)    * 次の変換に備えて保存
  2681.         move.w        d1,PtoA_Y-mpw(a6)
  2682.  
  2683. *--------------    PCM -> ADPCM 変換終了 ----------------
  2684.  
  2685.  
  2686. *        DMA 継続動作準備
  2687.  
  2688.         lea.l        -48(a0),a4
  2689.  
  2690.         lea.l        DMA3,a0
  2691.         move.w        sr,d0
  2692.         ori.w        #$0700,sr
  2693.         btst.b        #3,CSR(a0)        * CSR ACTビット(過負荷時のチェック)
  2694.         bne        @f
  2695.  
  2696.         addi.w        #1,overload_ctr-mpw(a6)
  2697.         bne        1f
  2698.         trap        #9
  2699.         lea.l        ch0_work(pc),a5
  2700.         REPT        CH_MAX
  2701.         clr.b        CH_PLAY_FLAG(a5)    * 演奏チャンネル演奏停止
  2702.         clr.b        CH_KEY_STAT(a5)        * KEY OFF
  2703.         lea.l        CH_WORK_SIZE(a5),a5
  2704.         ENDM
  2705.         REPT        EFCT_MAX
  2706.         clr.b        EFCT_PLAY_FLAG(a5)    * 効果音チャンネル演奏停止
  2707.         lea.l        EFCT_WORK_SIZE(a5),a5
  2708.         ENDM
  2709.         clr.b        EFCT_PLAY_FLAG(a5)    * IOCSの演奏停止
  2710.  
  2711.         clr.l        play_flag-mpw(a6)    * 演奏フラグの取消
  2712.         clr.b        ADPCM_SYSWORK.w        * ADPCMのIOCS 停止
  2713.         bra        mpcm_overload        * ADPCM停止処理へ
  2714.  
  2715. 1:        moveq.l        #MIX_SIZE,d1
  2716.         moveq.l        #5,d2
  2717.  
  2718.         move.w        d1,MTC(a0)        * $88+$80を1回分転送
  2719.         move.b        d2,MFC(a0)
  2720.         move.l        #dummy_ADPCM,MAR(a0)
  2721.  
  2722.         move.w        d1,BTC(a0)        * $88+$80をもう1回分転送
  2723.         move.b        d2,BFC(a0)
  2724.         move.l        a4,BAR(a0)        * 今回処理したADPCMを通常で出力
  2725.  
  2726.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2727.         move.b        #$c8,DCCR(a0)        * 動作開始/継続モード/転送終了割込あり
  2728.  
  2729.         move.w        d0,sr
  2730.     .ifdef    DEBUG
  2731.         movea.l        ofwrite-mpw(a6),a0
  2732.         move.b        #$ff,(a0)+        * オーバーフローを知らせる
  2733.         move.l        a0,ofwrite-mpw(a6)
  2734.     .endif
  2735.         tst.b        mpcm_debug-mpw(a6)
  2736.         beq        mpcm_loop
  2737.         move.w        #%01111_01111_01111_0,TEXT_PALET * 過負荷時は白
  2738.         bra        mpcm_loop        * もう一回頑張れ
  2739.  
  2740.  
  2741. @@:        move.w        #MIX_SIZE,BTC(a0)    * 通常処理
  2742.         move.b        #$05,BFC(a0)
  2743.         move.l        a4,BAR(a0)
  2744.         move.b        CSR(a0),CSR(a0)        * CSR all clear
  2745.         move.b        #$48,DCCR(a0)        * 継続動作/転送終了割込あり
  2746.  
  2747. mpcm_end:    tst.b        mpcm_debug-mpw(a6)
  2748.         beq        1f
  2749.         move.w        #%00000_00000_00000_0,TEXT_PALET    * 終了
  2750. 1:        move.w        #-1,mpcm_nest
  2751.         move.w        #-100,overload_ctr
  2752.         move.l        (sp)+,MFP+$12        * IMRA/IMRB 復帰
  2753.  
  2754.         movem.l        (sp)+,d0-d7/a0-a6
  2755.         rte
  2756.  
  2757.  
  2758. *===============================================================
  2759. *        ADPCM処理ルーチン
  2760. *===============================================================
  2761.  
  2762.         .include    ADP_high.has
  2763.         .include    ADP_low.has
  2764.         .include    ADP_0101.has
  2765.         .include    ADP_0203.has
  2766.         .include    ADP_0102.has
  2767.         .include    ADP_0103.has
  2768.         .include    ADP_0104.has
  2769.  
  2770. AtoP_LOOP:    move.l        a2,CH_LOOP_X(a5)    * ループ先頭でのX
  2771.         move.w        d1,CH_LOOP_Y(a5)    * ループ先頭での基本PCM
  2772.         movea.l        CH_LPEND_ADR(a5),a3
  2773.         lea.l        AtoP_LPEND(pc),a4
  2774.         move.l        a3,CH_TRAP_ADR(a5)
  2775.         move.l        a4,CH_TRAP_ROUTINE(a5)    * 次のトラップは、ループ終了位置
  2776.         rts
  2777.  
  2778. AtoP_LPEND:    tst.l        CH_LPTIME(a5)        * 無限ループか?
  2779.         beq        1f
  2780.         sub.l        #1,CH_LPTIME_CTR(a5)
  2781.         beq        2f
  2782. 1:        movea.l        CH_LOOP_X(a5),a2
  2783.         move.w        CH_LOOP_Y(a5),d1
  2784.         movea.l        CH_LPSTART_ADR(a5),a0    * ループポイントに戻る
  2785.         rts
  2786. 2:        movea.l        CH_END_ADR(a5),a3    * a3.l = ADPCMデータ終了アドレス
  2787.         cmpa.l        a3,a0
  2788.         bcc        AtoP_END        * LPEND (>)= DATA ENDの場合に対処
  2789.         lea.l        AtoP_END(pc),a4        * a4.l = データ終了処理アドレス
  2790.         move.l        a3,CH_TRAP_ADR(a5)
  2791.         move.l        a4,CH_TRAP_ROUTINE(a5)    * 次のトラップは、データ終了位置
  2792.         rts
  2793.  
  2794. AtoP_END:    addq.l        #4,sp            * 戻りアドレス破棄
  2795.         clr.b        CH_PLAY_FLAG(a5)    * 演奏停止
  2796.         clr.b        CH_KEY_STAT(a5)        * KEY OFF状態
  2797.         rts
  2798.  
  2799.  
  2800. *===============================================================
  2801. *        16bitPCM処理ルーチン
  2802. *===============================================================
  2803.  
  2804.         .include    P16_high.has
  2805.         .include    P16_low.has
  2806.         .include    P16_0101.has
  2807.         .include    P16_0203.has
  2808.         .include    P16_0102.has
  2809.         .include    P16_0103.has
  2810.         .include    P16_0104.has
  2811.  
  2812.  
  2813. PCM16_LPEND:    tst.l        CH_LPTIME(a5)
  2814.         beq        1f            * 無限ループだった場合
  2815. 3:        sub.l        #1,CH_LPTIME_CTR(a5)
  2816.         beq        2f
  2817. 1:        suba.l        a3,a0            * 現在アドレス-終点アドレスでアドレス差分計算
  2818.         adda.l        CH_LPSTART_ADR(a5),a0    * それをループ始点に足し、現在アドレスとする
  2819.         cmpa.l        a3,a0
  2820.         bcc        3b            * まだループ終点より大きい
  2821.         rts
  2822. 2:        movea.l        CH_END_ADR(a5),a3    * 次のトラップはデータ終了
  2823.         cmpa.l        a3,a0
  2824.         bcc        PCM16_END        * LPEND (>)= DATA END に対応
  2825.         lea.l        PCM16_END(pc),a4
  2826.         move.l        a3,CH_TRAP_ADR(a5)
  2827.         move.l        a4,CH_TRAP_ROUTINE(a5)
  2828.         rts
  2829.  
  2830. PCM16_END:    addq.l        #4,sp            * 戻りアドレス破棄
  2831.         clr.b        CH_PLAY_FLAG(a5)    * 演奏停止
  2832.         clr.b        CH_KEY_STAT(a5)        * KEY OFF状態
  2833.         rts
  2834.  
  2835.  
  2836. *===============================================================
  2837. *        8bitPCM処理ルーチン
  2838. *===============================================================
  2839.  
  2840.         .include    P8_high.has
  2841.         .include    P8_low.has
  2842.         .include    P8_0101.has
  2843.         .include    P8_0203.has
  2844.         .include    P8_0102.has
  2845.         .include    P8_0103.has
  2846.         .include    P8_0104.has
  2847.  
  2848. PCM8_LPEND:    tst.l        CH_LPTIME(a5)
  2849.         beq        1f            * 無限ループだった場合
  2850. 3:        sub.l        #1,CH_LPTIME_CTR(a5)
  2851.         beq        2f
  2852. 1:        suba.l        a3,a0            * 現在アドレス-終点アドレスでアドレス差分計算
  2853.         adda.l        CH_LPSTART_ADR(a5),a0    * それをループ始点に足し、現在アドレスとする
  2854.         cmpa.l        a3,a0
  2855.         bcc        3b            * まだループ終点より大きい
  2856.         rts
  2857. 2:        movea.l        CH_END_ADR(a5),a3    * 次のトラップはデータ終了
  2858.         cmpa.l        a3,a0
  2859.         bcc        PCM8_END        * LPEND (>)= DATA END に対応
  2860.         lea.l        PCM8_END(pc),a4
  2861.         move.l        a3,CH_TRAP_ADR(a5)
  2862.         move.l        a4,CH_TRAP_ROUTINE(a5)
  2863.         rts
  2864.  
  2865. PCM8_END:    addq.l        #4,sp            * 戻りアドレス破棄
  2866.         clr.b        CH_PLAY_FLAG(a5)    * 演奏停止
  2867.         clr.b        CH_KEY_STAT(a5)        * KEY OFF状態
  2868.         rts
  2869.  
  2870. *===============================================================
  2871. *        登録データが無い場合の処理ルーチン
  2872. *===============================================================
  2873.  
  2874. NO_PCM:        clr.b        CH_PLAY_FLAG(a5)    * 演奏停止
  2875.         clr.b        CH_KEY_STAT(a5)        * KEY OFF状態
  2876.         rts
  2877.  
  2878. *===============================================================
  2879. *        各PCMキーオフ消音処理ルーチン
  2880. *===============================================================
  2881.  
  2882. make_keyoff_PCM:
  2883.         move.w        CH_LAST_VPCM(a5),d0    * 最後の音量変換付PCM
  2884.         move.w        d0,d1
  2885.         asr.w        #4,d1            * d1.w=d0.w/16
  2886.         moveq.l        #4-1,d2
  2887. @@:        add.w        d0,(a1)+        * 音量を下げていって消音
  2888.         sub.w        d1,d0
  2889.         add.w        d0,(a1)+
  2890.         sub.w        d1,d0
  2891.         add.w        d0,(a1)+
  2892.         sub.w        d1,d0
  2893.         add.w        d0,(a1)+
  2894.         sub.w        d1,d0
  2895.         dbra        d2,@b
  2896.  
  2897.         clr.w        CH_LAST_VPCM(a5)    * 音量変換付PCM=0
  2898.         rts
  2899.  
  2900. *===============================================================
  2901. *        IOCS専用ADPCM処理ルーチン
  2902. *===============================================================
  2903.  
  2904.         .include    ADP_EFFECT.has
  2905.         .include    P16_EFFECT.has
  2906.         .include    P8_EFFECT.has
  2907.  
  2908.  
  2909. *===============================================================
  2910. *        デバッグ専用ルーチン
  2911. *===============================================================
  2912. .ifdef    DEBUG
  2913.  
  2914. print_str:    movem.l        a0-a3,-(sp)
  2915.         lea.l        $f3a000,a0        * character ROM addr
  2916.         movea.l        text_adr(pc),a3
  2917.  
  2918. prtstr_loop:    moveq.l        #0,d0
  2919.         move.b        (a1)+,d0
  2920.         beq        prtstr_end
  2921.         cmp.b        #CR,d0
  2922.         beq        prtstr_CR
  2923.         cmp.b        #LF,d0
  2924.         beq        prtstr_LF
  2925.         lsl.w        #3,d0        * 8倍
  2926.         lea.l        (a0,d0.w),a2
  2927.         move.b        (a2)+,(a3)+
  2928.         move.b        (a2)+,128*1-1(a3)
  2929.         move.b        (a2)+,128*2-1(a3)
  2930.         move.b        (a2)+,128*3-1(a3)
  2931.         move.b        (a2)+,128*4-1(a3)
  2932.         move.b        (a2)+,128*5-1(a3)
  2933.         move.b        (a2)+,128*6-1(a3)
  2934.         move.b        (a2)+,128*7-1(a3)
  2935.         bra        prtstr_loop
  2936.  
  2937. prtstr_CR:    move.l        a3,d0
  2938.         andi.l        #$00ffff80,d0
  2939.         movea.l        d0,a3
  2940.         bra        prtstr_loop
  2941.  
  2942. prtstr_LF:    lea.l        128*8(a3),a3
  2943.         bra        prtstr_loop
  2944.  
  2945. prtstr_end:    move.l        a3,text_adr
  2946.         movem.l        (sp)+,a0-a3
  2947.         rts
  2948.  
  2949. print_char:    movem.l        a0-a3,-(sp)
  2950.         lea.l        $f3a000,a0
  2951.         movea.l        text_adr(pc),a3
  2952.  
  2953.         moveq.l        #0,d0
  2954.         move.b        d1,d0
  2955.         beq        prtchr_end
  2956.         cmp.b        #CR,d0
  2957.         beq        prtchr_CR
  2958.         cmp.b        #LF,d0
  2959.         beq        prtchr_LF
  2960.         lsl.w        #3,d0        * 8倍
  2961.         lea.l        (a0,d0.w),a2
  2962.         move.b        (a2)+,(a3)+
  2963.         move.b        (a2)+,128*1-1(a3)
  2964.         move.b        (a2)+,128*2-1(a3)
  2965.         move.b        (a2)+,128*3-1(a3)
  2966.         move.b        (a2)+,128*4-1(a3)
  2967.         move.b        (a2)+,128*5-1(a3)
  2968.         move.b        (a2)+,128*6-1(a3)
  2969.         move.b        (a2)+,128*7-1(a3)
  2970.  
  2971. prtchr_end:    move.l        a3,text_adr
  2972.         movem.l        (sp)+,a0-a3
  2973.         rts
  2974.  
  2975. prtchr_CR:    move.l        a3,d0
  2976.         andi.l        #$00ffff80,d0
  2977.         movea.l        d0,a3
  2978.         bra        prtchr_end
  2979.  
  2980. prtchr_LF:    lea.l        128*8(a3),a3
  2981.         bra        prtchr_end
  2982.  
  2983. text_adr:    .dc.l        TEXT_RAM            * text ram addr counter
  2984.  
  2985. VALtoSTRl:    move.l        #'0000',d1
  2986.         lea.l        STRbuffl(pc),a0
  2987.         move.l        d1,(a0)+
  2988.         move.l        d1,(a0)+
  2989. @@:        move.l        d0,d1
  2990.         andi.w        #$0f,d1
  2991.         move.b        ConvTbl(pc,d1.w),-(a0)
  2992.         lsr.l        #4,d0
  2993.         bne        @b
  2994.         rts
  2995.  
  2996. STRbuffl:    .dc.b        '00000000',0
  2997.         .even
  2998.  
  2999. VALtoSTRw:    move.l        #'0000',d1
  3000.         lea.l        STRbuffw+4(pc),a0
  3001.         move.l        d1,(a0)+
  3002.         andi.l        #$0000ffff,d0
  3003. @@:        move.l        d0,d1
  3004.         andi.w        #$0f,d1
  3005.         move.b        ConvTbl(pc,d1.w),-(a0)
  3006.         lsr.l        #4,d0
  3007.         bne        @b
  3008.         rts
  3009.  
  3010. STRbuffw:    .dc.b        '    0000',0
  3011.         .even
  3012.  
  3013. VALtoSTRb:    move.w        #'00',d1
  3014.         lea.l        STRbuffb+6(pc),a0
  3015.         move.w        d1,(a0)+
  3016.         andi.l        #$000000ff,d0
  3017. @@:        move.l        d0,d1
  3018.         andi.w        #$0f,d1
  3019.         move.b        ConvTbl(pc,d1.w),-(a0)
  3020.         lsr.l        #4,d0
  3021.         bne        @b
  3022.         rts
  3023.  
  3024. STRbuffb:    .dc.b        '      00',0
  3025.         .even
  3026.  
  3027. ConvTbl:    .dc.b        '0123456789ABCDEF'
  3028.         .even
  3029.  
  3030. .endif
  3031.  
  3032. *▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
  3033. *
  3034. *        でっかいテーブル
  3035. *
  3036. *△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△
  3037.  
  3038. AtoP_tbl:    .ds.b        49*256*6        * ADPCM -> PCM 変換テーブル
  3039. PtoA_tbl:    .ds.b        32014            * PCM -> ADPCM 作成テーブル
  3040.  
  3041.  
  3042.  
  3043. *▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
  3044. *
  3045. *        非常駐部分
  3046. *
  3047. *△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△
  3048.  
  3049.         .text
  3050.  
  3051. mpcm_start:    pea.l        title_mes(pc)
  3052.         DOS        _PRINT
  3053.         addq.l        #4,sp
  3054.         movea.l        a0,a6            * a0/a6=メモリ管理ポインタ
  3055.         bsr        option_check
  3056.  
  3057. keep_check:    movea.l        (a6),a6
  3058.         cmpa.l        #$10000,a6
  3059.         bcs        not_keeped        * 常駐してない
  3060.         lea.l        $100(a6),a5
  3061.         move.l        (a5),d1
  3062.         cmp.l        header,d1
  3063.         bne        keep_check        * ヘッダが一致しない
  3064.         move.l        4(a5),d1
  3065.         cmp.l        header+4,d1
  3066.         bne        keep_check        * ヘッダが一致しない
  3067.         bra        keeped            * 常駐していた
  3068.  
  3069.  
  3070. *        << 常駐していなかった場合 >>
  3071.  
  3072. not_keeped:    btst.b        #0,option_flag(pc)    * -r check
  3073.         bne        error0            * 常駐してないのに常駐解除は出来ない
  3074.  
  3075.         btst.b        #1,option_flag(pc)    * -d check
  3076.         beq        @f
  3077.         tst.b        D_option_work
  3078.         bmi        1f
  3079.         move.b        D_option_work(pc),mpcm_debug
  3080.         bra        @f
  3081. 1:        st.b        mpcm_debug        * degug フラグ状態反転
  3082.  
  3083. @@:        move.w        F_option_work(pc),frq_offset
  3084.  
  3085. @@:        btst.b        #4,option_flag(pc)    * -v check
  3086.         beq        @f
  3087.         move.l        a6,-(sp)
  3088.         moveq.l        #1,d1
  3089.         lea.l        mpw,a6
  3090.         jsr        func_8005
  3091.         move.l        (sp)+,a6
  3092.         st.b        volume_mode        * -v flag set
  3093.  
  3094. @@:        bsr        make_AtoP_tbl        * ADPCM -> PCM 変換テーブル作成
  3095.         bsr        make_PtoA_tbl        * PCM -> ADPCM 変換テーブル作成
  3096.         bsr        init_mpcm        * 割り込みワーク/ADPCM/DMA初期化
  3097.         bsr        init_iocs        * iocsコールの処理横取り初期化
  3098.  
  3099.         pea.l        keep_mes(pc)
  3100.         DOS        _PRINT
  3101.         addq.l        #4,sp
  3102.  
  3103. .ifdef    DEBUG
  3104.         bsr        MPCM_DEBUG
  3105. .endif
  3106.  
  3107.         clr.w        -(sp)
  3108.         lea.l        mpcm_start(pc),a0    * コンパイル時の為
  3109.         lea.l        header,a1
  3110.         suba.l        a1,a0
  3111.         move.l        a0,-(sp)
  3112.         DOS        _KEEPPR            * 常駐して終了
  3113.  
  3114. *        << 既に常駐していた場合 >>
  3115.  
  3116. keeped:        tst.b        option_flag
  3117.         beq        error1
  3118.  
  3119.         btst.b        #0,option_flag(pc)    * r オプションが指定されている?
  3120.         beq        @f            * されてない
  3121.  
  3122.         tst.b        mpcm_locked-header(a5)    * 常駐解除処理
  3123.         bne        error2            * 占有されている
  3124.  
  3125.         move.w        #$01ff,d0
  3126.         trap        #1            * MPCM 全チャンネルキーオフ
  3127.  
  3128.         clr.l        -(sp)
  3129.         DOS        _SUPER
  3130.         move.l        d0,(sp)
  3131.  
  3132. *        lea.l        mpcm-header(a5),a0
  3133. *        cmp.l        $0130.w,a0
  3134. *        bne        errorC            * ベクタが書き換えられている
  3135.  
  3136.         move.b        #$01,$E92001        * ADPCM 停止
  3137.  
  3138.         move.w        sr,d0            * sr 保存
  3139.         ori.w        #$0700,sr        * 割り込み禁止
  3140.  
  3141.         move.l        trap1_vec_buff-header(a5),$0084.w    * trap 1 ベクタ戻す
  3142.         move.l        DMA_vec_buff-header(a5),$01a8.w        * DMA転送終了割り込み
  3143.         move.l        DMAERR_vec_buff-header(a5),$01ac.w    * DMA転送エラー割り込み
  3144.  
  3145.         move.w        d0,sr            * 割り込み許可
  3146.  
  3147.         bsr        recover_iocs        * IOCSコールを元に戻す
  3148.  
  3149.         DOS        _SUPER
  3150.         addq.l        #4,sp
  3151.  
  3152.         pea.l        $10(a6)
  3153.         DOS        _MFREE
  3154.         pea.l        free_mes(pc)
  3155.         DOS        _PRINT
  3156.         addq.l        #8,sp
  3157.         bra        keeped_end        * 常駐解除終了
  3158.  
  3159. @@:        btst.b        #1,option_flag(pc)    * -dオプションあり?
  3160.         beq        @f
  3161.         tst.b        D_option_work
  3162.         bmi        1f
  3163.         move.b        D_option_work(pc),mpcm_debug-header(a5)
  3164.         bra        2f
  3165. 1:        tas.b        mpcm_debug-header(a5)    * degug フラグ状態反転
  3166.         beq        2f
  3167.         clr.b        mpcm_debug-header(a5)
  3168. 2:        pea.l        change_debugmode_mes(pc)
  3169.         DOS        _PRINT
  3170.         addq.l        #4,sp
  3171.  
  3172. @@:        btst.b        #3,option_flag(pc)    * -s option
  3173.         beq        @f
  3174.  
  3175.         pea.l        debug_mode_mes(pc)    * デバッグモード状態表示
  3176.         DOS        _PRINT
  3177.         tst.b        mpcm_debug-header(a5)
  3178.         beq        1f
  3179.         pea.l        on_mes(pc)
  3180.         DOS        _PRINT
  3181.         bra        2f
  3182. 1:        pea.l        off_mes(pc)
  3183.         DOS        _PRINT
  3184. 2:        addq.l        #8,sp
  3185.  
  3186.         pea.l        adpcm_mode_mes(pc)    * adpcm動作周波数表示
  3187.         DOS        _PRINT
  3188.         move.w        frq_offset-header(a5),d0
  3189.         beq        2f
  3190.         cmpi.w        #4*2,d0
  3191.         beq        1f
  3192.         pea.l        adpcm7k_mes(pc)
  3193.         bra        3f
  3194. 1:        pea.l        adpcm15k_mes(pc)
  3195.         bra        3f
  3196. 2:        pea.l        adpcm31k_mes(pc)
  3197. 3:        DOS        _PRINT
  3198.         addq.l        #8,sp
  3199.  
  3200.         pea.l        pitch_mode_mes(pc)
  3201.         DOS        _PRINT
  3202.         tst.b        pitch_mode-header(a5)
  3203.         beq        1f
  3204.         pea.l        p_lock_mes(pc)
  3205.         DOS        _PRINT
  3206.         bra        2f
  3207. 1:        pea.l        p_unlock_mes(pc)
  3208.         DOS        _PRINT
  3209. 2:        addq.l        #8,sp
  3210.  
  3211.         pea.l        volume_mode_mes(pc)
  3212.         DOS        _PRINT
  3213.         tst.b        volume_mode-header(a5)
  3214.         beq        1f
  3215.         pea.l        v16_mes(pc)
  3216.         DOS        _PRINT
  3217.         bra        2f
  3218. 1:        pea.l        v128_mes(pc)
  3219.         DOS        _PRINT
  3220. 2:        addq.l        #8,sp
  3221.  
  3222.         tst.b        mpcm_locked-header(a5)
  3223.         beq        no_lock_entry        * 占有されてないよ
  3224.         pea.l        lock_entry_mes(pc)
  3225.         DOS        _PRINT
  3226.         addq.l        #4,sp
  3227.  
  3228.         lea.l        mplock_app_name-header(a5),a0
  3229.         moveq.l        #32-1,d1
  3230. 1:        tst.b        (a0)
  3231.         beq        2f
  3232.         pea.l        (a0)
  3233.         DOS        _PRINT
  3234.         pea.l        crlf_mes(pc)
  3235.         DOS        _PRINT
  3236.         addq.l        #8,sp
  3237. 2:        lea.l        32(a0),a0
  3238.         dbra        d1,1b
  3239.  
  3240. @@:
  3241. keeped_end:    DOS        _EXIT
  3242.  
  3243.  
  3244. .ifdef DEBUG
  3245. *
  3246. *        MPCMのデバッグ用(本来不要)
  3247. *
  3248.  
  3249. MPCM_DEBUG:
  3250.         bsr        read_adpcm
  3251. break0:
  3252.         move.w        #$0200,d0
  3253.         lea.l        PCMHEADER(pc),a1
  3254.         trap        #1
  3255.         move.w        #$0300,d0    * 周波数
  3256.         moveq.l        #4,d1
  3257.         trap        #1
  3258.         move.w        #$0400,d0    * 音程
  3259.         move.w        #(64*64)+0,d1
  3260.         trap        #1
  3261.         move.w        #$0500,d0    * 音量
  3262.         moveq.l        #64,d1
  3263.         trap        #1
  3264.         move.w        #$0700,d0
  3265.         move.b        #$02,d1
  3266.         trap        #1
  3267. breakx:
  3268.         move.w        #$0000,d0    * KEY ON
  3269.         trap        #1
  3270.  
  3271. break1:
  3272.         move.w        #$0100,d0    * KEY OFF
  3273.         trap        #1
  3274.  
  3275.         rts
  3276.  
  3277.  
  3278. read_adpcm:    clr.w        -(sp)            *サンプルPCMの読み込み
  3279.         pea.l        PCMNAME(pc)
  3280.         DOS        _OPEN
  3281.         addq.l        #6,sp
  3282.         move.l        #-1,-(sp)
  3283.         pea.l        ADPCMBUFF
  3284.         move.w        d0,-(sp)
  3285.         DOS        _READ
  3286.         move.l        d0,PCMLEN
  3287. *        add.l        d0,d0
  3288. *        add.l        d0,d0
  3289. *        move.l        d0,PCMLEN
  3290.         move.w        (sp)+,d0
  3291.         addq.l        #8,sp
  3292.         move.w        d0,-(sp)
  3293.         DOS        _CLOSE
  3294.         addq.l        #2,sp
  3295.         rts
  3296.  
  3297.  
  3298. PCMHEADER:    .dc.l        $ff400000
  3299.         .dc.l        ADPCMBUFF
  3300. PCMLEN:        .dc.l        0
  3301. LPSTOFS:    .dc.l        $00000100
  3302. LPEDOFS:    .dc.l        $00000110
  3303. LPCNT:        .dc.l        $00001000
  3304.  
  3305. PCMNAME:    .dc.b        'C:\wacho\xpcm\V3\nob\TEST1.P8',0
  3306.         .even
  3307.  
  3308.  
  3309. .endif
  3310.  
  3311. *=======================================================
  3312. * option_check    : オプション判定&フラグとワークのセット
  3313. * call        : (a2)~=コマンドライン
  3314. * return    : (option_flag)とそれぞれのワークに値をセット
  3315. * breaks    : d0,d1,a2
  3316. *=======================================================
  3317. option_check:    clr.b        option_flag        * flag clear
  3318.         move.w        #4*2,F_option_work    * 周波数バッファ
  3319.         addq.l        #1,a2
  3320.  
  3321. opt_chk0:    move.b        (a2)+,d0
  3322.         tst.b        d0
  3323.         beq        opt_ret
  3324.         cmpi.b        #'/',d0            * option ?
  3325.         beq        opt_chk1
  3326.         cmpi.b        #'-',d0            * option ?
  3327.         beq        opt_chk1
  3328.         cmpi.b        #TAB,d0            * TAB    ?
  3329.         beq        opt_chk0
  3330.         cmpi.b        #' ',d0            * SPACE ?
  3331.         beq        opt_chk0
  3332.         bra        usage            * 使用法表示
  3333.  
  3334. opt_chk1:    move.b        (a2)+,d0
  3335.         andi.b        #$df,d0            * 大文字に揃える
  3336.  
  3337.         cmpi.b        #'R',d0            * r = 常駐解除
  3338.         bne        opt_chk2
  3339.         bset.b        #0,option_flag        * bit0 = r 用フラグ
  3340.         bra        opt_chk0
  3341.  
  3342. opt_chk2:    cmpi.b        #'D',d0            * d = デバッグモード
  3343.         bne        opt_chk3
  3344.         bset.b        #1,option_flag        * bit1 = d 用フラグ
  3345.         move.b        (a2),d0
  3346.         cmpi.b        #'0',d0            * Not Debug mode !
  3347.         beq        1f
  3348.         cmpi.b        #'1',d0            * Debug mode !
  3349.         bne        2f
  3350. 1:        addq.l        #1,a2
  3351.         subi.b        #'0',d0
  3352.         move.b        d0,D_option_work    * Write work : 0 / 1 
  3353.         bra        opt_chk0
  3354. 2:        st.b        D_option_work        * write work : -1 (reverse)
  3355.         bra        opt_chk0
  3356.  
  3357. opt_chk3:    cmpi.b        #'F',d0            * h = ADPCM 動作周波数
  3358.         bne        opt_chk4
  3359.         move.b        (a2),d0
  3360.         andi.b        #$df,d0            * 大文字に揃える
  3361.         cmpi.b        #'H',d0            * High frq!
  3362.         bne        1f
  3363.         addq.l        #1,a2
  3364.         clr.w        F_option_work
  3365.         bra        opt_chk0
  3366. 1:        cmpi.b        #'L',d0            * Low frq!
  3367.         bne        usage
  3368.         addq.l        #1,a2
  3369.         move.w        #4*4,F_option_work
  3370.         bra        opt_chk0
  3371.  
  3372.  
  3373. opt_chk4:    cmpi.b        #'S',d0            * s = mpcm状態表示
  3374.         bne        opt_chk5
  3375.         bset.b        #3,option_flag        * bit3 = s 用フラグ
  3376.         bra        opt_chk0
  3377.  
  3378. opt_chk5:    cmpi.b        #'V',d0            * v = 音量16段階固定
  3379.         bne        opt_chk6
  3380.         bset.b        #4,option_flag        * bit4 = s 用フラグ
  3381.         bra        opt_chk0
  3382.  
  3383. opt_chk6:    bra        usage            * 使用法表示
  3384.  
  3385. opt_ret:    rts
  3386.  
  3387. *===============================================================
  3388. * error        : 非常駐部分エラー処理
  3389. * usage        : 使い方表示
  3390. *===============================================================
  3391. error0:        pea.l        error0_mes(pc)
  3392.         bra        error
  3393. error1:        pea.l        error1_mes(pc)
  3394.         bra        error
  3395. error2:        pea.l        error2_mes(pc)
  3396.         bra        error
  3397. error3:        pea.l        error3_mes(pc)
  3398.         bra        error
  3399. usage:        pea.l        usage_mes(pc)
  3400.         bra        error
  3401.  
  3402. no_lock_entry:    pea.l        no_lock_entry_mes(pc)
  3403.         bra        error
  3404.  
  3405. error:        DOS        _PRINT
  3406.         addq.l        #4,sp
  3407.         moveq.l        #-1,d0
  3408.         DOS        _EXIT2
  3409.  
  3410. *===============================================================
  3411. * make_AtoP_tbl    : ADPCM -> PCM 変換テーブル作成
  3412. *===============================================================
  3413.  
  3414. make_AtoP_tbl:    lea.l        AtoP_tbl,a0        * テーブル作成領域アドレス
  3415.         lea.l        conv_tbl0(pc),a1    * ADPCM<->PCM変換作業表0
  3416.         lea.l        conv_tbl1(pc),a2    * ADPCM<->PCM変換作業表1
  3417.         lea.l        conv_tbl2(pc),a3    * ADPCM<->PCM変換作業表2
  3418.  
  3419.         moveq.l        #0,d1            * d1.b=X(0~48)のカウンタ
  3420. 1:        moveq.l        #0,d0            * d0.b=ADPCM(0~255)のカウンタ
  3421.  
  3422. 2:        move.w        d0,d2
  3423.         andi.w        #$000f,d2
  3424.         add.w        d2,d2            * d2.w=(A mod 16)*2
  3425.         move.w        (a1,d2.w),d3        * d3.w=C
  3426.         move.l        d1,d4            * d4.lの上位ワードは常に$0000
  3427.         add.w        d4,d4
  3428.         muls.w        (a2,d4.w),d3        * X から D を求める
  3429.         bpl        @f
  3430.         addq.w        #7,d3            * 切り捨て考慮
  3431. @@:        asr.w        #3,d3            * d3.w = (C*D)/8=dy1
  3432.         move.w        d1,d4
  3433.         add.w        (a3,d2.w),d4        * d4.w = X1 = X0+E
  3434.         bpl        @f
  3435.         moveq.l        #0,d4
  3436. @@:        cmp.w        #48+1,d4
  3437.         bcs        @f
  3438.         moveq.l        #48,d4
  3439.  
  3440. @@:        move.w        d0,d2
  3441.         andi.w        #$00f0,d2
  3442.         lsr.w        #3,d2            * d2=(A\16)*2
  3443.         move.w        (a1,d2.w),d6        * d6=C
  3444.         move.w        d4,d5
  3445.         add.w        d5,d5
  3446.         muls.w        (a2,d5.w),d6
  3447.         bpl        @f
  3448.         addq.w        #7,d6            * 切り捨て考慮
  3449. @@:        asr.w        #3,d6            * d6.w = (C*D)/8=dy2
  3450.         add.w        (a3,d2.w),d4        * d4.w = X2 = X0+E
  3451.         bpl        @f
  3452.         moveq.l        #0,d4
  3453. @@:        cmp.w        #48+1,d4
  3454.         bcs        @f
  3455.         moveq.l        #48,d4
  3456.  
  3457. @@:        move.w        d3,(a0)+        * dy1
  3458.         move.w        d6,256*2-2(a0)        * dy2それぞれをテーブルに格納
  3459.         lsl.w        #8,d4
  3460.         add.w        d4,d4
  3461.         move.w        d4,d6
  3462.         add.w        d4,d4
  3463.         add.l        d6,d4            * X2*256*2*3倍
  3464.         add.l        #AtoP_tbl+2,d4
  3465.         sub.l        a0,d4
  3466.         move.w        d4,256*2*2-2(a0)    * X2テーブルへのアドレス差分
  3467.  
  3468.         add.b        #1,d0
  3469.         bne        2b
  3470.  
  3471.         adda.w        #256*2*2,a0
  3472.         add.w        #1,d1
  3473.         cmp.w        #48+1,d1
  3474.         bcs        1b
  3475.         rts
  3476.  
  3477. *===============================================================
  3478. * make_PtoA_tbl    : PCM -> ADPCM 変換テーブル作成
  3479. *===============================================================
  3480.  
  3481. make_PtoA_tbl:    lea.l        PtoA_tbl,a0        * テーブル作成領域
  3482.         lea.l        conv_tbl0(pc),a1    * Oh!X 表2
  3483.         lea.l        conv_tbl1(pc),a2    * Oh!X 表3
  3484.         lea.l        conv_tbl2(pc),a3    * Oh!X 表4
  3485.  
  3486.  
  3487.         lea.l        conv_tbl3(pc),a4    * Xの先頭アドレステーブル作成
  3488.         movea.l        a4,a5
  3489.         moveq.l        #0,d7
  3490. 1:        move.w        d7,d0
  3491.         add.w        d0,d0
  3492.         move.w        (a2,d0.w),d0
  3493.         muls.w        #7,d0
  3494.         lsr.w        #2,d0            * d0.w = d0.w*7/4
  3495.         add.w        #2+8*6,d0
  3496.         add.l        (a5)+,d0
  3497.         btst.l        #0,d0
  3498.         beq        @f
  3499.         addq.l        #1,d0            * テーブルは偶数からだから
  3500. @@:        move.l        d0,(a5)
  3501.         addq.w        #1,d7
  3502.         cmpi.w        #48,d7
  3503.         bcs        1b
  3504.  
  3505.  
  3506.         moveq.l        #0,d6            * X(0~49)のカウンタ
  3507. 1:        movea.l        a0,a5            * a5.l = 現在のXのベースアドレス
  3508.  
  3509.         move.w        d6,d5
  3510.         add.w        d5,d5
  3511.         move.w        (a2,d5.w),d5        * d5.w = D (Xに対応する予測値)
  3512.  
  3513.         move.w        d5,d4
  3514.         muls.w        #7,d4
  3515.         lsr.w        #2,d4            * d4.w = D*7/4
  3516.         move.w        d4,(a0)+        * D*7/4 (最大△PCM値) 書き込み
  3517.  
  3518.         moveq.l        #7,d0
  3519. 2:        move.w        d0,d1            * Xに対応するヘッダ部分作成
  3520.         lsl.w        #4,d1
  3521.         or.w        d0,d1
  3522.         move.w        d1,(a0)+        * ADPCMデータ 書き込み
  3523.  
  3524.         move.w        d0,d1
  3525.         add.w        d1,d1
  3526.         move.w        d5,d2
  3527.         muls.w        (a1,d1.w),d2
  3528.         lsr.w        #3,d2
  3529.         move.w        d2,(a0)+        * 実際の△PCM 書き込み
  3530.  
  3531.         move.w        d6,d2
  3532.         add.w        (a3,d1.w),d2
  3533.         bpl        @f
  3534.         moveq.l        #0,d2
  3535. @@:        cmpi.w        #48+1,d2
  3536.         bcs        @f
  3537.         moveq.l        #48,d2
  3538. @@:        add.w        d2,d2
  3539.         add.w        d2,d2
  3540.         move.l        (a4,d2.w),d1
  3541.         sub.l        a0,d1
  3542.         move.w        d1,(a0)+        * 次のXアドレスへのオフセット書き込み
  3543.         subq.b        #1,d0
  3544.         bge        2b
  3545.  
  3546.  
  3547.         move.w        d4,d7
  3548.         btst.l        #0,d7
  3549.         bne        @f
  3550.         sub.w        #1,d7            * d7.w = PCM のカウンタ
  3551.  
  3552. @@:        moveq.l        #0,d4
  3553.  
  3554. 2:        move.l        d4,d0            * ヘッダ部分へのオフセット計算
  3555.         add.l        d0,d0
  3556.         add.l        d0,d0            * d0.l = PCM * 4
  3557.         divs.w        d5,d0            * d0.w = PCM*4 / D
  3558.  
  3559.         cmpi.w        #$0007+1,d0
  3560.         bcs        @f
  3561.         moveq.l        #7,d0            * d1 > 7 なら d1=7
  3562.  
  3563. @@:        eori.w        #$0007,d0        * 0~7 -> 7~0 に変換
  3564.         add.w        d0,d0
  3565.         move.w        d0,d1
  3566.         add.w        d0,d0
  3567.         add.w        d1,d0
  3568.         move.b        d0,(a0)+        * オフセット書き込み
  3569.         addq.w        #1,d4
  3570.         dbra        d7,2b
  3571.  
  3572.         addq.w        #1,d6
  3573.         cmp.w        #48+1,d6
  3574.         bcs        1b
  3575.  
  3576.         rts
  3577.  
  3578. *===============================================================
  3579. * init_mpcm    : 割り込みワーク/ADPCM/DMAの初期化
  3580. *===============================================================
  3581.  
  3582. init_mpcm:    lea.l        mpw,a6
  3583.         jsr        init_channel_work    * 全チャンネルワーク初期化
  3584.  
  3585.         clr.l        -(sp)
  3586.         DOS        _SUPER
  3587.         move.l        d0,(sp)
  3588.  
  3589.         move.w        sr,d0            * sr 保存
  3590.         ori.w        #$0700,sr        * 割り込み禁止
  3591.  
  3592.         move.l        $0084.w,d1        * trap1
  3593.         cmp.l        #$00ff0000,d1
  3594.         bcs        trap1_error        * 何者かがtrap#1を占有している
  3595.  
  3596.  
  3597.         clr.b        ADPCM_SYSWORK.w        * IOCS 初期化
  3598.  
  3599. *        ADPCMの初期化
  3600.         move.w        frq_offset-mpw(a6),d0
  3601.         beq        2f
  3602.         cmpi.w        #4*2,d0
  3603.         beq        1f
  3604.         move.w        #$0203,d1        * ADPCM 7.8kHz
  3605.         bra        @f
  3606. 1:        move.w        #$0403,d1        * ADPCM 15.6kHz
  3607.         bra        @f
  3608. 2:        move.w        #$0603,d1        * ADPCM 31.2kHz
  3609. @@:        jsr        ADPCM_mode        * 周波数15.6kHz/PAN左右
  3610.         move.b        #$02,ADPCM+1        * ADPCM 再生ON
  3611.  
  3612. *        DMA 初期化
  3613. @@:        lea.l        DMA3,a0
  3614.         move.b        #$04,SCR(a0)        * SCR clear
  3615.         move.b        #$10,DCCR(a0)        * CCR DMA停止割り込み無し
  3616.         move.b        #$80,DCR(a0)        * DCR clear
  3617.         move.b        #$02,OCR(a0)        * OCR clear
  3618.         move.b        #$01,CPR(a0)
  3619.         move.b        #$05,MFC(a0)
  3620.         move.b        #$05,DFC(a0)
  3621.  
  3622. *        割り込みベクタのフック
  3623.         move.l        $0084.w,trap1_vec_buff    * trap1
  3624.         move.l        #mpcm_trap1,$0084.w
  3625.         move.l        $01a8.w,DMA_vec_buff    * DMA転送終了割り込み
  3626.         move.l        #mpcm,$01a8.w
  3627.         move.l        $01ac.w,DMAERR_vec_buff    * DMA転送エラー割り込み
  3628.         move.l        #mpcm_err,$01ac.w
  3629.  
  3630.         move.w        d0,sr            * 割り込み許可
  3631.  
  3632.         lea.l        mplock_app_name-mpw(a6),a0    * mpcm lock app名初期化
  3633.         moveq.l        #32-1,d0
  3634. @@:        clr.b        (a0)
  3635.         lea.l        32(a0),a0
  3636.         dbra        d0,@b
  3637.  
  3638.         clr.b        mpcm_locked-mpw(a6)
  3639.  
  3640.         DOS        _SUPER
  3641.         addq.l        #4,sp
  3642.  
  3643.         rts
  3644.  
  3645. trap1_error:    move.w        d0,sr            * 割り込み許可
  3646.         DOS        _SUPER
  3647.         addq.l        #4,sp
  3648.         bra        error3
  3649.  
  3650. *===============================================================
  3651. * init_iocs    : IOCS処理ルーチンのエントリ
  3652. *===============================================================
  3653.  
  3654. init_iocs:    lea.l        iocs_vecs,a2
  3655.         move.w        #$0160,d1
  3656.         lea.l        mpcm_iocs_60,a1
  3657.         IOCS        _B_INTVCS        * IOCS _ADPCMOUTをフック
  3658.         move.l        d0,(a2)+        * 前のを保存
  3659.         addq.w        #1,d1
  3660.         lea.l        mpcm_iocs_61,a1
  3661.         IOCS        _B_INTVCS        * IOCS _ADPCMINPをフック
  3662.         move.l        d0,(a2)+
  3663.         addq.w        #1,d1
  3664.         lea.l        mpcm_iocs_62,a1
  3665.         IOCS        _B_INTVCS        * IOCS _ADPCMAOTをフック
  3666.         move.l        d0,(a2)+
  3667.         addq.w        #1,d1
  3668.         lea.l        mpcm_iocs_63,a1
  3669.         IOCS        _B_INTVCS        * IOCS _ADPCMAINをフック
  3670.         move.l        d0,(a2)+
  3671.         addq.w        #1,d1
  3672.         lea.l        mpcm_iocs_64,a1
  3673.         IOCS        _B_INTVCS        * IOCS _ADPCMLOTをフック
  3674.         move.l        d0,(a2)+
  3675.         addq.w        #1,d1
  3676.         lea.l        mpcm_iocs_65,a1
  3677.         IOCS        _B_INTVCS        * IOCS _ADPCMLINをフック
  3678.         move.l        d0,(a2)+
  3679.         addq.w        #1,d1
  3680.         lea.l        mpcm_iocs_66,a1
  3681.         IOCS        _B_INTVCS        * IOCS _ADPCMSNSをフック
  3682.         move.l        d0,(a2)+
  3683.         addq.w        #1,d1
  3684.         lea.l        mpcm_iocs_67,a1
  3685.         IOCS        _B_INTVCS        * IOCS _ADPCMMODをフック
  3686.         move.l        d0,(a2)+
  3687.         rts
  3688.  
  3689. *===============================================================
  3690. * recover_iocs    : IOCS処理ルーチンを元に戻す
  3691. *===============================================================
  3692.  
  3693. recover_iocs:    lea.l        iocs_vecs-header(a5),a2
  3694.         move.w        #$0160,d1
  3695.         movea.l        (a2)+,a1
  3696.         IOCS        _B_INTVCS        * IOCS _ADPCMOUTを戻す
  3697.         addq.w        #1,d1
  3698.         movea.l        (a2)+,a1
  3699.         IOCS        _B_INTVCS        * IOCS _ADPCMINPを戻す
  3700.         addq.w        #1,d1
  3701.         movea.l        (a2)+,a1
  3702.         IOCS        _B_INTVCS        * IOCS _ADPCMAOTを戻す
  3703.         addq.w        #1,d1
  3704.         movea.l        (a2)+,a1
  3705.         IOCS        _B_INTVCS        * IOCS _ADPCMAINを戻す
  3706.         addq.w        #1,d1
  3707.         movea.l        (a2)+,a1
  3708.         IOCS        _B_INTVCS        * IOCS _ADPCMLOTを戻す
  3709.         addq.w        #1,d1
  3710.         movea.l        (a2)+,a1
  3711.         IOCS        _B_INTVCS        * IOCS _ADPCMLINを戻す
  3712.         addq.w        #1,d1
  3713.         movea.l        (a2)+,a1
  3714.         IOCS        _B_INTVCS        * IOCS _ADPCMSNSを戻す
  3715.         addq.w        #1,d1
  3716.         movea.l        (a2)+,a1
  3717.         IOCS        _B_INTVCS        * IOCS _ADPCMMODを戻す
  3718.         rts
  3719.  
  3720.  
  3721. *===============================================================
  3722. *         非常駐部分固定データ
  3723. *===============================================================
  3724.         .data
  3725.  
  3726. title_mes:    .dc.b        'Modulatable (ad)PCM driver MPCM.x version. 0.45 '
  3727.         .dc.b        'copyright (c) 1994,95,96 by wachoman'
  3728. crlf_mes:    .dc.b        CR,LF,0
  3729.  
  3730. keep_mes:    .dc.b        '常駐しました.',CR,LF,0
  3731. free_mes:    .dc.b        '常駐解除しました.',CR,LF,0
  3732.  
  3733. error0_mes:    .dc.b        '常駐していません.',CR,LF,0
  3734. error1_mes:    .dc.b        '既に常駐しています.',CR,LF,0
  3735. error2_mes:    .dc.b        '占有されているため常駐解除できません.',CR,LF,0
  3736. error3_mes:    .dc.b        'TRAP#1が既に使用されています. 常駐できません.',CR,LF,0
  3737.  
  3738. usage_mes:    .dc.b        'usage  :  mpcm.x [option]',CR,LF
  3739.         .dc.b        'option :  /r      ・・・・・・・・・ 常駐解除',CR,LF
  3740.         .dc.b        '          /d[0/1] ・・・・・・・・・ デバッグモード変更',CR,LF
  3741.         .dc.b        '          /v      ・・・・・・・・・ 音量16段階固定          (常駐時のみ有効)',CR,LF
  3742.         .dc.b        '          /fh     ・・・・・・・・・ ADPCM動作周波数 31.2kHz (常駐時のみ有効)',CR,LF
  3743.         .dc.b        '          /fl     ・・・・・・・・・ ADPCM動作周波数  7.8kHz (常駐時のみ有効)',CR,LF
  3744.         .dc.b        '          /s      ・・・・・・・・・ mpcm状態表示',CR,LF
  3745.         .dc.b        0
  3746.  
  3747. change_debugmode_mes:
  3748.         .dc.b        'デバッグモードを変更しました.',CR,LF,0
  3749. no_lock_entry_mes:
  3750.         .dc.b        'MPCMは占有されていません.',CR,LF,0
  3751. lock_entry_mes:
  3752.         .dc.b        '-- MPCMを占有しているアプリケーション一覧 --',CR,LF,0
  3753.  
  3754. debug_mode_mes:    .dc.b        'デバッグモード :',0
  3755. adpcm_mode_mes:    .dc.b        'ADPCM動作周波数:',0
  3756. pitch_mode_mes:    .dc.b        '音程変換       :',0
  3757. volume_mode_mes:.dc.b        '音量変換       :',0
  3758. on_mes:        .dc.b        'on',CR,LF,0
  3759. off_mes:    .dc.b        'off',CR,LF,0
  3760. adpcm7k_mes:    .dc.b        '7.8kHz',CR,LF,0
  3761. adpcm15k_mes:    .dc.b        '15.6kHz',CR,LF,0
  3762. adpcm31k_mes:    .dc.b        '31.2kHz',CR,LF,0
  3763. v16_mes:    .dc.b        '16段階',CR,LF,0
  3764. v128_mes:    .dc.b        '128段階',CR,LF,0
  3765. p_lock_mes:    .dc.b        '原音固定',CR,LF,0
  3766. p_unlock_mes:    .dc.b        '変換可能',CR,LF,0
  3767.  
  3768.  
  3769.         .even
  3770.  
  3771. *        Oh!X ADPCM データ -> 倍率変換表
  3772. conv_tbl0:    .dc.w          1,   3,   5,   7,   9,  11,  13,  15
  3773.         .dc.w         -1,  -3,  -5,  -7,  -9, -11, -13, -15
  3774.  
  3775. *        Oh!X 予測指標(X) -> 予測値(D) 変換表
  3776. conv_tbl1:    .dc.w          16,  17,  19,  21,  23,  25,  28,  31
  3777.         .dc.w          34,  37,  41,  45,  50,  55,  60,  66
  3778.         .dc.w          73,  80,  88,  97, 107, 118, 130, 143
  3779.         .dc.w         157, 173, 190, 209, 230, 253, 279, 307
  3780.         .dc.w         337, 371, 408, 449, 494, 544, 598, 658
  3781.         .dc.w         724, 796, 875, 963,1060,1166,1282,1411
  3782.         .dc.w        1552
  3783.  
  3784. *        Oh!X ADPCMデータ -> 予測指標修正値 変換表
  3785. conv_tbl2:    .dc.w         -1,  -1,  -1,  -1,   2,   4,   6,   8
  3786.         .dc.w         -1,  -1,  -1,  -1,   2,   4,   6,   8
  3787.  
  3788. *        PCM -> ADPCM表 Xに対応する変換表トップアドレス格納バッファ
  3789. conv_tbl3:    .dc.l        PtoA_tbl
  3790.         .ds.l        48
  3791.  
  3792.  
  3793. *===============================================================
  3794. *         非常駐部分ワークエリア
  3795. *===============================================================
  3796.         .bss
  3797.  
  3798. option_flag:    .ds.b        1            * bit 0 : -r option
  3799.                             * bit 1 : -d
  3800. D_option_work:    .ds.b        1            * D option work
  3801.         .even
  3802. F_option_work:    .ds.w        1            * F option work
  3803.  
  3804. .ifdef    DEBUG
  3805.  
  3806. ADPCMBUFF:    .ds.b        64*1024
  3807.  
  3808. .endif
  3809.         .end        mpcm_start
  3810.